Skip to content

Commit 6445240

Browse files
authored
Merge pull request #1358 from Dstack-TEE/fix/supervisor-log-reopen
fix(supervisor): reopen the log only when it is actually rotated
2 parents dc7925f + 167f7d0 commit 6445240

2 files changed

Lines changed: 30 additions & 5 deletions

File tree

‎dstack/supervisor/src/process.rs‎

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,16 @@ async fn redirect(mut input: impl AsyncRead + Unpin, to: String) {
376376
}
377377
}
378378

379+
/// inotify reports our own `write_all` as `Modify(Data)`, so only a removal or a
380+
/// rename (logrotate's default mode) means the path no longer names our file.
381+
fn is_rotation(kind: &notify::EventKind) -> bool {
382+
use notify::event::{EventKind, ModifyKind};
383+
matches!(
384+
kind,
385+
EventKind::Remove(_) | EventKind::Modify(ModifyKind::Name(_))
386+
)
387+
}
388+
379389
async fn try_redirect(input: &mut (impl AsyncRead + Unpin), to: String) -> Result<()> {
380390
let dst_path = Path::new(&to);
381391
let dst_path_buf = dst_path.to_path_buf();
@@ -386,9 +396,7 @@ async fn try_redirect(input: &mut (impl AsyncRead + Unpin), to: String) -> Resul
386396
notify::recommended_watcher(move |res: Result<notify::Event, notify::Error>| {
387397
if let Ok(event) = res {
388398
// Check if the event affects our specific file
389-
if (event.kind.is_remove() || event.kind.is_modify())
390-
&& event.paths.iter().any(|p| p == &dst_path_buf)
391-
{
399+
if is_rotation(&event.kind) && event.paths.iter().any(|p| p == &dst_path_buf) {
392400
let _ = reopen_tx.blocking_send(());
393401
}
394402
}
@@ -438,3 +446,20 @@ async fn try_redirect(input: &mut (impl AsyncRead + Unpin), to: String) -> Resul
438446
}
439447
}
440448
}
449+
450+
#[cfg(test)]
451+
mod log_rotation_tests {
452+
use super::is_rotation;
453+
use notify::event::{DataChange, EventKind, ModifyKind, RemoveKind, RenameMode};
454+
455+
#[test]
456+
fn only_a_removal_or_a_rename_is_a_rotation() {
457+
assert!(is_rotation(&EventKind::Remove(RemoveKind::File)));
458+
assert!(is_rotation(&EventKind::Modify(ModifyKind::Name(
459+
RenameMode::From
460+
))));
461+
assert!(!is_rotation(&EventKind::Modify(ModifyKind::Data(
462+
DataChange::Any
463+
))));
464+
}
465+
}

‎dstack/vmm/src/app.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,8 +1882,8 @@ fn append_boot_separator(path: &std::path::Path) {
18821882
/// Logs a CVM writes into its work directory, subject to retention.
18831883
///
18841884
/// stdout and stderr are written by the supervisor, which always opens them
1885-
/// with `append(true)` and reopens them when they change, so they satisfy
1886-
/// [`crate::logrotate`]'s contract no matter which VMM launched the VM.
1885+
/// with `append(true)`, so they satisfy [`crate::logrotate`]'s contract no
1886+
/// matter which VMM launched the VM.
18871887
/// serial.log is written by QEMU, whose fd only appends when *we* passed
18881888
/// `logappend=on`, so it is included only when `serial` says so.
18891889
fn rotatable_logs(work_dir: &VmWorkDir, serial: bool) -> Vec<PathBuf> {

0 commit comments

Comments
 (0)