Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add_watch() returns Error if any subdirectories contain symlinks. #17

Closed
SirVer opened this issue Jun 22, 2015 · 12 comments
Closed

add_watch() returns Error if any subdirectories contain symlinks. #17

SirVer opened this issue Jun 22, 2015 · 12 comments

Comments

@SirVer
Copy link

SirVer commented Jun 22, 2015

Tested on linux, notify 2.0.0.

@SirVer
Copy link
Author

SirVer commented Jun 22, 2015

Here is a minimal failing example: https://github.com/SirVer/notify_crash

Crash occur-es in this line on unwrap:
https://github.com/SirVer/notify_crash/blob/master/src/main.rs#L19

@SirVer SirVer changed the title Panics if any subdirectories used in add_watch() contains symlinks. add_watch() returns Error if any subdirectories contain symlinks. Jun 22, 2015
@passcod
Copy link
Member

passcod commented Jun 22, 2015

Can you post the output of the crash if any?

@SirVer
Copy link
Author

SirVer commented Jun 23, 2015

Most certainly:

$ git clone https://github.com/SirVer/notify_crash
Cloning into 'notify_crash'...
remote: Counting objects: 8, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 8 (delta 0), reused 8 (delta 0), pack-reused 0
Unpacking objects: 100% (8/8), done.
Checking connectivity... done.
$ cd notify_crash
$ cargo run
   Compiling gcc v0.3.8
   Compiling libc v0.1.8
   Compiling walker v1.0.0
   Compiling bitflags v0.2.1
   Compiling log v0.3.1
   Compiling inotify v0.1.12
   Compiling time v0.1.26
   Compiling notify v2.0.0
   Compiling notify_crash v0.1.0 (file:///tmp/notify_crash)
src/main.rs:27:9: 27:10 warning: unused variable: `e`, #[warn(unused_variables)] on by default
src/main.rs:27     Err(e) => println!("Error")
                       ^
src/main.rs:13:7: 13:12 warning: variable does not need to be mutable, #[warn(unused_mut)] on by default
src/main.rs:13   let mut w: Result<RecommendedWatcher, Error> = Watcher::new(tx);
                     ^~~~~
     Running `target/debug/notify_crash`
thread '<main>' panicked at 'called `Result::unwrap()` on an `Err` value: Io(Error { repr: Os(40) })', ../src/libcore/result.rs:731
An unknown error occurred

To learn more, run the command again with --verbose.
$ RUST_BACKTRACE=1 cargo run
     Running `target/debug/notify_crash`
thread '<main>' panicked at 'called `Result::unwrap()` on an `Err` value: Io(Error { repr: Os(40) })', ../src/libcore/result.rs:731
stack backtrace:
   1:     0x7f593d23549e - sys::backtrace::write::he24e072826f78dbbpqs
   2:     0x7f593d238bbc - panicking::on_panic::hfe8dee88ad5f1f8f69w
   3:     0x7f593d22d11e - rt::unwind::begin_unwind_inner::h30a8282e6074626cKPw
   4:     0x7f593d22da7c - rt::unwind::begin_unwind_fmt::h0d67ce05a74a7ba4QOw
   5:     0x7f593d238626 - rust_begin_unwind
   6:     0x7f593d263f14 - panicking::panic_fmt::h03749e86046e7c85E8B
   7:     0x7f593d1e2255 - result::Result<T, E>::unwrap::h12153668657867214282
                        at ../src/libcore/macros.rs:28
   8:     0x7f593d1d64d5 - main::haf030d8e0024f90alaa
                        at src/main.rs:19
   9:     0x7f593d23d958 - rust_try_inner
  10:     0x7f593d23d945 - rust_try
  11:     0x7f593d23a627 - rt::lang_start::hdadb5fc58c5eeff334w
  12:     0x7f593d1ea9db - main
  13:     0x7f593cc05ec4 - __libc_start_main
  14:     0x7f593d1d6138 - <unknown>
  15:                0x0 - <unknown>
An unknown error occurred

To learn more, run the command again with --verbose.

@SirVer
Copy link
Author

SirVer commented Jun 25, 2015

Ping? This is quite the blocker for me and I have no idea what might be wrong here.

@passcod
Copy link
Member

passcod commented Jun 25, 2015

Ah, sorry, I tend to do open-source work during weekends. Here's a brain dump if you want to investigate:

This is most certainly going to be an inotify issue. There's two components at play: the recursive watcher which is in rsnotify code, and the inotify API. I'd recommend reading through the entire inotify man page, looking for any mention of behaviour related to symlinks.

Gut feeling is that the recursive watcher is seeing the symlink as a directory and trying to get inotify to place a watch on that but it can't or fails for some other reason. Resolution here would be to detect that something is a symlink and do dereference or just ignore it completely, or some other behaviour.

Another thing to investigate is if this only happens with symlinks, or if hardlinks cause a panic as well. They shouldn't, due to their different nature, but you never know. Also, it would be interesting to try with a symlink that's pointing to a file, and a symlink that's pointing to a folder, and finally a dangling symlink. You could push it even further to see what happens when going across filesystem boundaries, i.e. mount a disk (or loopback image if that's easier) in a subdirectory and ask rsnotify to kindly watch the parent directory.

Finally, try to figure out what exactly is an IO Error with the Rust signature Error { repr: Os(40) }. It could be that Os(int) is just a wrapper for "operating system" ints, like OsStrs are strings, or it could be that it's an OS Error with a code of 40, and those error codes are documented. That task will require going through the Rust documentation and possibly source to find what the signature means, and then going through Linux manpages for an "error code 40" related to inotify and/or I/O.

Hope that helps, if you have trouble I'll take a look this weekend anyway.

@SirVer
Copy link
Author

SirVer commented Jun 26, 2015

Thanks for all the insight! I will not be able to look into this this weekend and next week. The weekend after I'll should have time again to look into your suggestions more specifically. If you already have found something out by then I will of course be most grateful too :)

@sunng87
Copy link

sunng87 commented Jul 6, 2015

I may have a similar issue when working with Emacs lockfile

Every time I made a change in emacs, error received:

Io(Error { repr: Os { code: 2, message: "No such file or directory" } })

ls -la shows the watched directory like:

 $ ls -al examples/templates  
total 12
drwxr-xr-x 2 nsun nsun 4096 Jul  6 21:04 .
drwxr-xr-x 3 nsun nsun 4096 Jul  4 10:37 ..
lrwxrwxrwx 1 nsun nsun   31 Jul  6 21:04 .#index.hbs -> nsun@thinkless.17462:1435199339
-rw-r--r-- 1 nsun nsun  279 Jul  6 20:57 index.hbs

@passcod
Copy link
Member

passcod commented Jul 6, 2015

@sunng87 Can you open a separate issue ? Yours happens at watch-time, when a file is changed. OP's happens at add_watch()-time, when a symlink is hit in the recursive descent. The issues may well be related, but I'd prefer to track both on their own.

@sunng87
Copy link

sunng87 commented Jul 6, 2015

Sure, I will.

@octplane
Copy link
Contributor

#define ELOOP           40      /* Too many symbolic links encountered */

Jus sayin' :)

@SirVer
Copy link
Author

SirVer commented Aug 31, 2015

@octplane Right, if the link is self referrencing, that is the error. Other links incur crashes too though:

$ g clone git@github.com:SirVer/notify_crash.git     
$ rm src/offending_link 
$ ln -s target src/offending_link #  now it is a broken link
$  cargo run                                                       
     Running `target/debug/notify_crash`
thread '<main>' panicked at 'called `Result::unwrap()` on an `Err` value: Io(Error { repr: Os { code: 2, message: "No such file or directory" } })', ../src/libcore/result.rs:734
$ rm src/offending_link
$ ln -s ../target src
This now runs.

passcod added a commit that referenced this issue Dec 6, 2015
Fixes #31
Might help with #17 and #21
passcod added a commit that referenced this issue Dec 7, 2015
Fixes #31
Might help with #17 and #21
passcod added a commit that referenced this issue Dec 7, 2015
Fixes #31
Might help with #17 and #21
@passcod
Copy link
Member

passcod commented Dec 27, 2015

This is probably fixed, from change in #44 and investigation in #47. Closing. Reopen (or open new issue) if it still happens for you.

@passcod passcod closed this as completed Dec 27, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants