notify icon indicating copy to clipboard operation
notify copied to clipboard

Bad file descriptor when using notify 4.0.15

Open lambda2501 opened this issue 4 years ago • 11 comments

System details

  • OS/Platform name and version: GNU/Linux Void Linux Kernel 5.10.14_1
  • Rust version (if building from source): rustc --version: 1.48.0
  • Notify version (or commit hash if building from git): 4.0.15
  • If you're coming from a project that makes use of Notify, what it is, and a link to the downstream issue if there is one: Using Zola, issue found in this topic
  • Filesystem type and options: ext4
  • On Linux: Kernel version: 5.10.14_1

What you did (as detailed as you can)

Because the use of the serve command from zola didn't work, I tried to look at the notify dependency as suggested by a zola user:

  • using this piece of code from rust documentation:
extern crate notify;

use notify::{Watcher, RecursiveMode, watcher};
use std::sync::mpsc::channel;
use std::time::Duration;

fn main() {
    // Create a channel to receive the events.
    let (tx, rx) = channel();

    // Create a watcher object, delivering debounced events.
    // The notification back-end is selected based on the platform.
    let mut watcher = watcher(tx, Duration::from_secs(10)).unwrap();

    // Add a path to be watched. All files and directories at that path and
    // below will be monitored for changes.
    watcher.watch("/home/test/notify", RecursiveMode::Recursive).unwrap();

    loop {
        match rx.recv() {
           Ok(event) => println!("{:?}", event),
           Err(e) => println!("watch error: {:?}", e),
        }
    }
}

get this error (full backtrace):

cargo run
    Updating crates.io index
  Downloaded mio-extras v2.0.6
  Downloaded lazycell v1.3.0
  Downloaded mio v0.6.23
  Downloaded net2 v0.2.37
  Downloaded notify v4.0.15
  Downloaded filetime v0.2.14
  Downloaded inotify v0.7.1
  Downloaded same-file v1.0.6
  Downloaded log v0.4.14
  Downloaded inotify-sys v0.1.5
  Downloaded walkdir v2.3.1
  Downloaded libc v0.2.86
  Downloaded 12 crates (845.6 KB) in 1.26s
   Compiling libc v0.2.86
   Compiling log v0.4.14
   Compiling cfg-if v1.0.0
   Compiling cfg-if v0.1.10
   Compiling bitflags v1.2.1
   Compiling slab v0.4.2
   Compiling lazycell v1.3.0
   Compiling same-file v1.0.6
   Compiling walkdir v2.3.1
   Compiling net2 v0.2.37
   Compiling iovec v0.1.4
   Compiling inotify-sys v0.1.5
   Compiling filetime v0.2.14
   Compiling inotify v0.7.1
   Compiling mio v0.6.23
   Compiling mio-extras v2.0.6
   Compiling notify v4.0.15
   Compiling testnotify v0.1.0 (/home/testing/testnotify)
    Finished dev [unoptimized + debuginfo] target(s) in 1m 33s
     Running `target/debug/testnotify`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Io(Os { code: 9, kind: Other, message: "Bad file descriptor" })', src/main.rs:9:60
stack backtrace:
   0:     0x55b234771610 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hc5cc02b3e453225b
   1:     0x55b23478b63c - core::fmt::write::h5437b03347b2ec7a
   2:     0x55b23476e195 - std::io::Write::write_fmt::h16241c6ed218e16f
   3:     0x55b2347739ad - std::panicking::default_hook::{{closure}}::h345f4275bb854b6c
   4:     0x55b234773658 - std::panicking::default_hook::he532b712c71e2106
   5:     0x55b234774091 - std::panicking::rust_panic_with_hook::hf0f7347c753b38c2
   6:     0x55b234773c39 - std::panicking::begin_panic_handler::{{closure}}::h274b8a0752683642
   7:     0x55b234771a7c - std::sys_common::backtrace::__rust_end_short_backtrace::hdb383c60eb8b212f
   8:     0x55b234773bf9 - rust_begin_unwind
   9:     0x55b23478a951 - core::panicking::panic_fmt::h8d2c19297fe96b44
  10:     0x55b23478a773 - core::option::expect_none_failed::h1a6f64ce49780e5b
  11:     0x55b2346b8690 - core::result::Result<T,E>::unwrap::h153698ba41e7649b
                               at /builddir/rustc-1.48.0-src/library/core/src/result.rs:973
  12:     0x55b2346afc67 - testnotify::main::hc6d080588637a33e
                               at /home/testing/testnotify/src/main.rs:9
  13:     0x55b2346ad74b - core::ops::function::FnOnce::call_once::hc7cabb8185039193
                               at /builddir/rustc-1.48.0-src/library/core/src/ops/function.rs:227
  14:     0x55b2346af67e - std::sys_common::backtrace::__rust_begin_short_backtrace::he0bb11180eda92c4
                               at /builddir/rustc-1.48.0-src/library/std/src/sys_common/backtrace.rs:137
  15:     0x55b2346ad201 - std::rt::lang_start::{{closure}}::h7d1e44096e4ec86b
                               at /builddir/rustc-1.48.0-src/library/std/src/rt.rs:66
  16:     0x55b2347744b7 - std::rt::lang_start_internal::h0c3fae9f987cf9c0
  17:     0x55b2346ad1d7 - std::rt::lang_start::h13b856a3d9a8c2be
                               at /builddir/rustc-1.48.0-src/library/std/src/rt.rs:65
  18:     0x55b2346aff5a - main
  19:     0x7fd8c666ae0a - __libc_start_main
                               at /builddir/glibc-2.32/csu/../csu/libc-start.c:314
  20:     0x55b2346ad0ca - _start
  21:                0x0 - <unknown>

What you expected

I was expected it working

What happened

I got an error as described.

lambda2501 avatar Feb 16 '21 11:02 lambda2501

I can't seem to reproduce this, especially not "Bad file descriptor". Do you have any kind of special file system underlying this ? For example fuse mounts (remote stuff) or such things ? Is this always reproducible (for example across reboots)?

0xpr03 avatar Feb 17 '21 16:02 0xpr03

Could you retry this with the following: cargo.toml dependency entry

notify = "5.0.0-pre.5"

main.rs

use notify::{Watcher, RecommendedWatcher, RecursiveMode, Result};

fn main() -> Result<()> {
    // Automatically select the best implementation for your platform.
    let mut watcher: RecommendedWatcher = Watcher::new_immediate(|res| {
        match res {
           Ok(event) => println!("event: {:?}", event),
           Err(e) => println!("watch error: {:?}", e),
        }
    })?;

    // Add a path to be watched. All files and directories at that path and
    // below will be monitored for changes.
    watcher.watch("/home/test/notify", RecursiveMode::Recursive)?;
    
    loop {
        // just sleep
        std::thread::sleep_ms(100000);
    }

    Ok(())
}

0xpr03 avatar Feb 17 '21 17:02 0xpr03

With your changes, I got this when running cargo run

Compiling testnotify v0.1.0 (/home/testing/testnotify)
warning: use of deprecated function `std::thread::sleep_ms`: replaced by `std::thread::sleep`
  --> src/main.rs:14:9
   |
14 |         std::thread::sleep_ms(100000);
   |         ^^^^^^^^^^^^^^^^^^^^^
   |
   = note: `#[warn(deprecated)]` on by default

warning: unreachable expression
  --> src/main.rs:17:5
   |
13 | /     loop {
14 | |         std::thread::sleep_ms(100000);
15 | |     }
   | |_____- any code following this expression is unreachable
16 |
17 |       Ok(())
   |       ^^^^^^ unreachable expression
   |
   = note: `#[warn(unreachable_code)]` on by default

warning: 2 warnings emitted

    Finished dev [unoptimized + debuginfo] target(s) in 0.51s
     Running `target/debug/testnotify`
Error: Error { kind: Io(Os { code: 9, kind: Other, message: "Bad file descriptor" }), paths: [] }

lambda2501 avatar Feb 17 '21 19:02 lambda2501

I can't seem to reproduce this, especially not "Bad file descriptor". Do you have any kind of special file system underlying this ? For example fuse mounts (remote stuff) or such things ? Is this always reproducible (for example across reboots)?

Do any of these apply ? Because based on your output its not dependent on some of the recent changes and happens regardless of the major version. And as long as I can't reproduce this, it's pretty hard to pin from where we get invalid file handles.

0xpr03 avatar Feb 17 '21 19:02 0xpr03

I have nothing exotic as you ask. No special file system, no fuse mounts. I retried after reboot, same behaviour. I do not know where to look at. I'm using the official package from voidlinux repository.

lambda2501 avatar Feb 21 '21 10:02 lambda2501

Ok thanks, problem is that this will make it kinda guesswork to trace down (and requires more work to inspect).

To rule out the possibility of user limitations regarding file permissions and watch permissions: Does it change anything if you run this example as root (sudo) ?

Also: It does happen regardless of the directory you're trying to watch ? Like a folder that only contains ~2 files and no active process that is changing things or locking them. For example the src folder of this example should work without much external influence.

0xpr03 avatar Feb 21 '21 14:02 0xpr03

I have nothing exotic as you ask. No special file system, no fuse mounts. I retried after reboot, same behaviour. I do not know where to look at. I'm using the official package from voidlinux repository.

I'm having the same issue using mdBook from the Void Linux repos, makes me think it's a distro-specific issue.

chowning the directory doesn't fix the issue but running as root does.

NeelChotai avatar Mar 07 '22 16:03 NeelChotai

Ok, my issue was also on VoidLinux. So it could be because of the Void package ? Using root is not a solution, right ? Any new idea ?

lambda2501 avatar Apr 11 '22 07:04 lambda2501

got same problem. notify is not helpful with this error message.

on linux notify uses inotify, install inotify-tools and do : inotifywatch and You will know what's the problem.

in my case this fixed the problem : just do

sudo sysctl fs.inotify.max_user_instances=8192
sudo sysctl fs.inotify.max_user_watches=524288
sudo sysctl -p

mi4uu avatar Aug 01 '22 10:08 mi4uu

I'm raising the inotify limit issue as something to be fixed via better error reporting. Possibly looking into whether inotifywatch has more than simple error-code catching to detect this issue. (In any other case this specific bad-file-descriptor error is unrecoverable as it should never happen.)

For now documented in the next release via #395

0xpr03 avatar Aug 10 '22 12:08 0xpr03

Note that a similar issue is fixed in v5: https://github.com/notify-rs/notify/issues/266

Although the error message is different. Needs confirmation.

0xpr03 avatar Aug 10 '22 13:08 0xpr03