Skip to content

Conversation

@arp242
Copy link
Member

@arp242 arp242 commented Apr 25, 2024

This would result in two events being sent.

Fixes #299

…arent

This would result in two events being sent.

Fixes #299
@arp242 arp242 merged commit e75779f into main Apr 25, 2024
@arp242 arp242 deleted the p branch April 25, 2024 14:39
arp242 added a commit that referenced this pull request Apr 25, 2024
When watching /tmp, w.port.PathIsWatched(name) returned true for
/tmp/abc. PathIsWatched() checks:

	_, found := e.paths[path]
	return found

That e.paths gets set in EventPort.AssociatePath(), which is called by
Watcher.associateFile() for every path inside a watched directory. So it
can never watch subpaths.

Anyway, this seems safe to remove. Could check our own Watcher.dirs
state, but this doesn't seem needed (we already have tests for watching
the same path more than once).

(This came rolling out of #620).
arp242 added a commit that referenced this pull request Apr 26, 2024
When watching /tmp, w.port.PathIsWatched(name) returned true for
/tmp/abc. PathIsWatched() checks:

	_, found := e.paths[path]
	return found

That e.paths gets set in EventPort.AssociatePath(), which is called by
Watcher.associateFile() for every path inside a watched directory. So it
can never watch subpaths.

Anyway, this seems safe to remove. Could check our own Watcher.dirs
state, but this doesn't seem needed (we already have tests for watching
the same path more than once).

(This came rolling out of #620).
giorio94 added a commit to giorio94/cilium that referenced this pull request Nov 5, 2024
The clustermesh configuration watcher needs to explicitly watch the
config files to receive a notification when the underlying file gets
updated, if the path points to a symbolic link (e.g., when the folder
is mounted from a Kubernetes ConfigMap/Secret). However, the fsnotify
library slightly changed its behavior in the latest release [1], and no
longer propagates a remove event in case the parent directory is watched
as well. The reason being to prevent duplicate events, as it would be
generated both by the specific watcher and the parent directory watcher.
Still, the parent watcher doesn't emit the remove event in this context,
given that the symbolic link is not actually removed. In turn, opening
the possibility for race conditions in the current event processing
logic, which depends on always correctly re-establishing the watcher.

Let's address this by using two separate watchers, one for the config
directory itself and one for the individual config files, to ensure that
the remove event is correctly emitted when the symbolic link starts
pointing to a different file (hence breaking the existing watcher), so
that we can re-establish it.

[1]: fsnotify/fsnotify#620

Signed-off-by: Marco Iorio <[email protected]>
giorio94 added a commit to giorio94/fsnotify that referenced this pull request Nov 8, 2024
The blamed commit introduced a check to prevent sending a delete event
in case the parent is being watched as well. However, it accesses the
`watches.path` map without synchronization, possibly leading to a data
race in case the same map is accessed in parallel (e.g., by an `Add()`
operation). Let's fix this by grabbing the associated lock before
reading from the map.

Excerpt of the data race trace:

Write at 0x00c0004d8cf0 by goroutine 33:
  runtime.mapassign_faststr()
      golang.org/[email protected]/src/runtime/map_faststr.go:223 +0x0
  github.com/fsnotify/fsnotify.(*watches).updatePath()
      github.com/fsnotify/fsnotify/backend_inotify.go:163 +0x2b8
  github.com/fsnotify/fsnotify.(*inotify).register()
      github.com/fsnotify/fsnotify/backend_inotify.go:335 +0x1bd
  github.com/fsnotify/fsnotify.(*inotify).add()
      github.com/fsnotify/fsnotify/backend_inotify.go:331 +0xee
  github.com/fsnotify/fsnotify.(*inotify).AddWith()
      github.com/fsnotify/fsnotify/backend_inotify.go:296 +0x405
  github.com/fsnotify/fsnotify.(*inotify).Add()
      github.com/fsnotify/fsnotify/backend_inotify.go:253 +0x44
  github.com/fsnotify/fsnotify.(*Watcher).Add()
      github.com/fsnotify/fsnotify/fsnotify.go:313 +0x5ce

Previous read at 0x00c0004d8cf0 by goroutine 32:
  runtime.mapaccess2_faststr()
      golang.org/[email protected]/src/runtime/map_faststr.go:117 +0x0
  github.com/fsnotify/fsnotify.(*inotify).readEvents()
      github.com/fsnotify/fsnotify/backend_inotify.go:534 +0xd04
  github.com/fsnotify/fsnotify.newBufferedBackend.gowrap1()
      github.com/fsnotify/fsnotify/backend_inotify.go:195 +0x33

Fixes: e75779f ("inotify: don't send event for IN_DELETE_SELF when also watching the parent (fsnotify#620)")
giorio94 added a commit to giorio94/fsnotify that referenced this pull request Nov 8, 2024
The blamed commit introduced a check to prevent sending a delete event
in case the parent is being watched as well. However, it accesses the
`watches.path` map without synchronization, possibly leading to a data
race in case the same map is accessed in parallel (e.g., by an `Add()`
operation). Let's fix this by grabbing the associated lock before
reading from the map.

Excerpt of the data race trace:

Write at 0x00c0004d8cf0 by goroutine 33:
  runtime.mapassign_faststr()
      golang.org/[email protected]/src/runtime/map_faststr.go:223 +0x0
  github.com/fsnotify/fsnotify.(*watches).updatePath()
      github.com/fsnotify/fsnotify/backend_inotify.go:163 +0x2b8
  github.com/fsnotify/fsnotify.(*inotify).register()
      github.com/fsnotify/fsnotify/backend_inotify.go:335 +0x1bd
  github.com/fsnotify/fsnotify.(*inotify).add()
      github.com/fsnotify/fsnotify/backend_inotify.go:331 +0xee
  github.com/fsnotify/fsnotify.(*inotify).AddWith()
      github.com/fsnotify/fsnotify/backend_inotify.go:296 +0x405
  github.com/fsnotify/fsnotify.(*inotify).Add()
      github.com/fsnotify/fsnotify/backend_inotify.go:253 +0x44
  github.com/fsnotify/fsnotify.(*Watcher).Add()
      github.com/fsnotify/fsnotify/fsnotify.go:313 +0x5ce

Previous read at 0x00c0004d8cf0 by goroutine 32:
  runtime.mapaccess2_faststr()
      golang.org/[email protected]/src/runtime/map_faststr.go:117 +0x0
  github.com/fsnotify/fsnotify.(*inotify).readEvents()
      github.com/fsnotify/fsnotify/backend_inotify.go:534 +0xd04
  github.com/fsnotify/fsnotify.newBufferedBackend.gowrap1()
      github.com/fsnotify/fsnotify/backend_inotify.go:195 +0x33

Fixes: e75779f ("inotify: don't send event for IN_DELETE_SELF when also watching the parent (fsnotify#620)")
aanm pushed a commit to cilium/cilium that referenced this pull request Nov 14, 2024
The clustermesh configuration watcher needs to explicitly watch the
config files to receive a notification when the underlying file gets
updated, if the path points to a symbolic link (e.g., when the folder
is mounted from a Kubernetes ConfigMap/Secret). However, the fsnotify
library slightly changed its behavior in the latest release [1], and no
longer propagates a remove event in case the parent directory is watched
as well. The reason being to prevent duplicate events, as it would be
generated both by the specific watcher and the parent directory watcher.
Still, the parent watcher doesn't emit the remove event in this context,
given that the symbolic link is not actually removed. In turn, opening
the possibility for race conditions in the current event processing
logic, which depends on always correctly re-establishing the watcher.

Let's address this by using two separate watchers, one for the config
directory itself and one for the individual config files, to ensure that
the remove event is correctly emitted when the symbolic link starts
pointing to a different file (hence breaking the existing watcher), so
that we can re-establish it.

[1]: fsnotify/fsnotify#620

Signed-off-by: Marco Iorio <[email protected]>
giorio94 added a commit to giorio94/fsnotify that referenced this pull request Nov 14, 2024
The blamed commit introduced a check to prevent sending a delete event
in case the parent is being watched as well. However, it accesses the
`watches.path` map without synchronization, possibly leading to a data
race in case the same map is accessed in parallel (e.g., by an `Add()`
operation). Let's fix this by grabbing the associated lock before
reading from the map.

Excerpt of the data race trace:

Write at 0x00c0004d8cf0 by goroutine 33:
  runtime.mapassign_faststr()
      golang.org/[email protected]/src/runtime/map_faststr.go:223 +0x0
  github.com/fsnotify/fsnotify.(*watches).updatePath()
      github.com/fsnotify/fsnotify/backend_inotify.go:163 +0x2b8
  github.com/fsnotify/fsnotify.(*inotify).register()
      github.com/fsnotify/fsnotify/backend_inotify.go:335 +0x1bd
  github.com/fsnotify/fsnotify.(*inotify).add()
      github.com/fsnotify/fsnotify/backend_inotify.go:331 +0xee
  github.com/fsnotify/fsnotify.(*inotify).AddWith()
      github.com/fsnotify/fsnotify/backend_inotify.go:296 +0x405
  github.com/fsnotify/fsnotify.(*inotify).Add()
      github.com/fsnotify/fsnotify/backend_inotify.go:253 +0x44
  github.com/fsnotify/fsnotify.(*Watcher).Add()
      github.com/fsnotify/fsnotify/fsnotify.go:313 +0x5ce

Previous read at 0x00c0004d8cf0 by goroutine 32:
  runtime.mapaccess2_faststr()
      golang.org/[email protected]/src/runtime/map_faststr.go:117 +0x0
  github.com/fsnotify/fsnotify.(*inotify).readEvents()
      github.com/fsnotify/fsnotify/backend_inotify.go:534 +0xd04
  github.com/fsnotify/fsnotify.newBufferedBackend.gowrap1()
      github.com/fsnotify/fsnotify/backend_inotify.go:195 +0x33

Fixes: e75779f ("inotify: don't send event for IN_DELETE_SELF when also watching the parent (fsnotify#620)")
@zepatrik
Copy link

zepatrik commented Mar 17, 2025

How is this not a breaking change? We used the second event to distinguish between files and directories being deleted, which we cannot do at all now.
https://github.com/ory/x/blob/3886ee392c7016bca5a8b0fd0ffef24604085171/watcherx/directory.go#L45-L66
Why is this not an option instead?

Edit:
Other commits referencing this PR also had a similar issue, namely with k8s-atomic-write compatible watcher implementations. Taking inspiration there, the fix for us was to keep track of the files/directories that were watched, and using that to tell what exactly happened.

zepatrik added a commit to ory/x that referenced this pull request Mar 17, 2025
We need to figure out how to work around fsnotify/fsnotify#620
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Duplicate events for delete folder due to unix.IN_DELETE_SELF

3 participants