From 7de181e31173526fd63344b2c7bf8421a72407d6 Mon Sep 17 00:00:00 2001 From: Johnathan Sharratt Date: Wed, 7 Aug 2024 22:27:04 +1000 Subject: [PATCH 1/2] Added a patch for corrupt freed FD lists after replaying journals --- lib/wasix/src/fs/mod.rs | 5 +++++ lib/wasix/src/syscalls/journal/restore_snapshot.rs | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/lib/wasix/src/fs/mod.rs b/lib/wasix/src/fs/mod.rs index be813fea339..9b254206ae5 100644 --- a/lib/wasix/src/fs/mod.rs +++ b/lib/wasix/src/fs/mod.rs @@ -566,6 +566,11 @@ impl WasiFs { } } + pub fn clear_free_fd_list(&self) { + let mut freed_fds = self.freed_fds.write().unwrap(); + freed_fds.clear(); + } + /// Closes all the file handles. #[allow(clippy::await_holding_lock)] pub async fn close_all(&self) { diff --git a/lib/wasix/src/syscalls/journal/restore_snapshot.rs b/lib/wasix/src/syscalls/journal/restore_snapshot.rs index 883bd1d1812..930447349e6 100644 --- a/lib/wasix/src/syscalls/journal/restore_snapshot.rs +++ b/lib/wasix/src/syscalls/journal/restore_snapshot.rs @@ -62,6 +62,10 @@ pub unsafe fn restore_snapshot( .map_err(anyhow_err_to_runtime_err)?; } + // Reset the freed FD's so that none of them will be reused after + // the journal resumes + runner.ctx.data().state().fs.clear_free_fd_list(); + // Once we get to this point we are no longer replaying the journal // and need to clear this flag, the reason is that restoring the // background threads may immediately process requests while this From 7e449782529f45af58b3d83213619efd5d79a3ea Mon Sep 17 00:00:00 2001 From: Johnathan Sharratt Date: Wed, 7 Aug 2024 22:35:06 +1000 Subject: [PATCH 2/2] Added comments and renamed --- lib/wasix/src/fs/mod.rs | 8 +++++++- lib/wasix/src/syscalls/journal/restore_snapshot.rs | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/wasix/src/fs/mod.rs b/lib/wasix/src/fs/mod.rs index 9b254206ae5..a1fe86e05d0 100644 --- a/lib/wasix/src/fs/mod.rs +++ b/lib/wasix/src/fs/mod.rs @@ -566,7 +566,13 @@ impl WasiFs { } } - pub fn clear_free_fd_list(&self) { + /// We need to clear the freed FD list when the journal is replayed as it + /// will close lots of file descriptors which will fill the list. We clear + /// the list and allocate new FD's instead. + /// + /// This should only be used when the file descriptors are being managed + /// externally (e.g. journals) + pub(crate) fn clear_freed_fd_list(&self) { let mut freed_fds = self.freed_fds.write().unwrap(); freed_fds.clear(); } diff --git a/lib/wasix/src/syscalls/journal/restore_snapshot.rs b/lib/wasix/src/syscalls/journal/restore_snapshot.rs index 930447349e6..2f2699194bc 100644 --- a/lib/wasix/src/syscalls/journal/restore_snapshot.rs +++ b/lib/wasix/src/syscalls/journal/restore_snapshot.rs @@ -64,7 +64,7 @@ pub unsafe fn restore_snapshot( // Reset the freed FD's so that none of them will be reused after // the journal resumes - runner.ctx.data().state().fs.clear_free_fd_list(); + runner.ctx.data().state().fs.clear_freed_fd_list(); // Once we get to this point we are no longer replaying the journal // and need to clear this flag, the reason is that restoring the