Skip to content

Commit

Permalink
Better error handling in fsnotify recursive monitor (elastic#6949)
Browse files Browse the repository at this point in the history
When the recursive `file_monitor` is scanning a directory, it will ignore
paths that include an error. This is wrong, as sometimes those paths can
still be processed. For example, a directory might not be readable, but
the user wants to receive an event when it is created, even if its
contents can't be known.

This has been uncovered by recent changes in how directory errors are
reported by `filepath.Walk`, introduced in Go 1.10. Previously `walkFn`
would be called twice. Once without an error (when the directory has
been found during scan of the parent directory), and the second time
with an error (when access to the directory is attempted).
  • Loading branch information
adriansr authored and ruflin committed Apr 26, 2018
1 parent 5764ac8 commit 44ee36f
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 5 deletions.
2 changes: 1 addition & 1 deletion auditbeat/module/file_integrity/monitor/monitor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ func TestRecursiveSubdirPermissions(t *testing.T) {

assertNoError(t, os.Chmod(filepath.Join(outDir, "b"), 0))

// Setup watched on watched dir
// Setup watches on watched dir

watcher, err := New(true)
assertNoError(t, err)
Expand Down
13 changes: 9 additions & 4 deletions auditbeat/module/file_integrity/monitor/recursive.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,16 @@ func (watcher *recursiveWatcher) ErrorChannel() <-chan error {

func (watcher *recursiveWatcher) addRecursive(path string) error {
var errs multierror.Errors
err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
if err != nil {
errs = append(errs, errors.Wrapf(watcher.inner.Add(path), "recursion into dir '%s' failed", path))
return nil
err := filepath.Walk(path, func(path string, info os.FileInfo, fnErr error) error {
if fnErr != nil {
errs = append(errs, errors.Wrapf(fnErr, "error walking path '%s'", path))
// If FileInfo is not nil, the directory entry can be processed
// even if there was some error
if info == nil {
return nil
}
}
var err error
if info.IsDir() {
if err = watcher.tree.AddDir(path); err == nil {
if err = watcher.inner.Add(path); err != nil {
Expand Down

0 comments on commit 44ee36f

Please sign in to comment.