Skip to content

Commit ba3a53e

Browse files
authored
Merge pull request #2758 from didier-wenzek/fix/inotify-on-symlink
feat(watcher): use canonical path when watching a directory
2 parents 93799e8 + 2bf861f commit ba3a53e

File tree

3 files changed

+30
-8
lines changed
  • crates
    • common/tedge_utils/src
    • extensions/tedge_file_system_ext/src
    • tests/tedge_test_utils/src

3 files changed

+30
-8
lines changed

crates/common/tedge_utils/src/notify.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,11 @@ impl NotifyStream {
144144

145145
/// Will return an error if you try to watch a file/directory which doesn't exist
146146
pub fn add_watcher(&mut self, dir_path: &Path) -> Result<(), NotifyStreamError> {
147+
// Try to use canonical paths to avoid false negatives when dealing with symlinks
148+
let dir_path = dir_path.canonicalize()?;
147149
self.debouncer
148150
.watcher()
149-
.watch(dir_path, RecursiveMode::Recursive)?;
151+
.watch(&dir_path, RecursiveMode::Recursive)?;
150152

151153
Ok(())
152154
}

crates/extensions/tedge_file_system_ext/src/lib.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,9 @@ impl Default for FsWatchActorBuilder {
8484
}
8585

8686
impl MessageSource<FsWatchEvent, PathBuf> for FsWatchActorBuilder {
87-
fn register_peer(&mut self, config: PathBuf, sender: DynSender<FsWatchEvent>) {
88-
self.watch_dirs.push((config, sender));
87+
fn register_peer(&mut self, path: PathBuf, sender: DynSender<FsWatchEvent>) {
88+
let path = path.canonicalize().unwrap_or_else(|_| path.to_path_buf());
89+
self.watch_dirs.push((path, sender));
8990
}
9091
}
9192

@@ -173,12 +174,15 @@ mod tests {
173174

174175
#[tokio::test(flavor = "multi_thread")]
175176
async fn test_fs_events() -> Result<(), DynError> {
176-
let ttd = TempTedgeDir::new();
177+
let temp = TempTedgeDir::new();
178+
let ttd = temp.dir("watched-dir");
179+
let ttd_link = temp.link_dir(&ttd, "watched-symlink");
180+
let ttd_full = ttd.to_path_buf().canonicalize().unwrap().to_path_buf();
177181
let mut fs_actor_builder = FsWatchActorBuilder::new();
178182
let client_builder: SimpleMessageBoxBuilder<FsWatchEvent, NoMessage> =
179183
SimpleMessageBoxBuilder::new("FS Client", 5);
180184

181-
fs_actor_builder.register_peer(ttd.to_path_buf(), client_builder.get_sender());
185+
fs_actor_builder.register_peer(ttd_link.to_path_buf(), client_builder.get_sender());
182186

183187
let actor = fs_actor_builder.build();
184188
let client_box = client_builder.build();
@@ -195,9 +199,9 @@ mod tests {
195199
client_box
196200
.with_timeout(TEST_TIMEOUT)
197201
.assert_received_unordered([
198-
FsWatchEvent::Modified(ttd.to_path_buf().join("file_a")),
199-
FsWatchEvent::DirectoryCreated(ttd.to_path_buf().join("dir_b")),
200-
FsWatchEvent::Modified(ttd.to_path_buf().join("dir_b").join("file_b")),
202+
FsWatchEvent::Modified(ttd_full.to_path_buf().join("file_a")),
203+
FsWatchEvent::DirectoryCreated(ttd_full.to_path_buf().join("dir_b")),
204+
FsWatchEvent::Modified(ttd_full.to_path_buf().join("dir_b").join("file_b")),
201205
])
202206
.await;
203207

crates/tests/tedge_test_utils/src/fs.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,22 @@ impl TempTedgeDir {
6060
TempTedgeFile { file_path: path }
6161
}
6262

63+
pub fn link_dir(&self, original: &TempTedgeDir, link_name: &str) -> TempTedgeDir {
64+
let root = Utf8Path::from_path(self.temp_dir.path()).unwrap();
65+
let path = root.join(&self.current_file_path).join(link_name);
66+
67+
#[cfg(unix)]
68+
std::os::unix::fs::symlink(original.path(), &path).unwrap();
69+
70+
#[cfg(windows)]
71+
std::os::windows::fs::symlink_dir(original.path(), &path).unwrap();
72+
73+
TempTedgeDir {
74+
temp_dir: self.temp_dir.clone(),
75+
current_file_path: path,
76+
}
77+
}
78+
6379
pub fn path(&self) -> &Path {
6480
self.current_file_path.as_std_path()
6581
}

0 commit comments

Comments
 (0)