From 8f186a692fef7537a5ee4ecde1c3ec294d9c42c2 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 25 Jul 2024 12:49:43 +0200 Subject: [PATCH] Allow writing messages to debug: without preserving them in sys:log This would allow logd to write all received log messages to debug: without causing an infinite loop when it at the same time reads all messages in sys:log. --- src/arch/x86_shared/debug.rs | 6 +++--- src/scheme/debug.rs | 29 ++++++++++++++++++++++------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/arch/x86_shared/debug.rs b/src/arch/x86_shared/debug.rs index dbfdf674e5..576c22f56d 100644 --- a/src/arch/x86_shared/debug.rs +++ b/src/arch/x86_shared/debug.rs @@ -56,8 +56,8 @@ impl<'a> Writer<'a> { } } - pub fn write(&mut self, buf: &[u8]) { - { + pub fn write(&mut self, buf: &[u8], preserve: bool) { + if preserve { if let Some(ref mut log) = *self.log { log.write(buf); } @@ -100,7 +100,7 @@ impl<'a> Writer<'a> { impl<'a> fmt::Write for Writer<'a> { fn write_str(&mut self, s: &str) -> Result<(), fmt::Error> { - self.write(s.as_bytes()); + self.write(s.as_bytes(), true); Ok(()) } } diff --git a/src/scheme/debug.rs b/src/scheme/debug.rs index 8b8c8bbae9..f73dc8132b 100644 --- a/src/scheme/debug.rs +++ b/src/scheme/debug.rs @@ -40,6 +40,13 @@ pub fn debug_notify() { pub struct DebugScheme; +#[repr(usize)] +enum SpecialFds { + Default = !0, + NoPreserve = !0 - 1, + DisableGraphicalDebug = !0 - 2, +} + impl KernelScheme for DebugScheme { fn kopen(&self, path: &str, _flags: usize, ctx: CallerCtx) -> Result { if ctx.uid != 0 { @@ -47,13 +54,15 @@ impl KernelScheme for DebugScheme { } let num = match path { - "" => !0, + "" => SpecialFds::Default as usize, + + "no-preserve" => SpecialFds::NoPreserve as usize, "disable-graphical-debug" => { #[cfg(feature = "graphical_debug")] graphical_debug::fini(); - !0 - 1 + SpecialFds::DisableGraphicalDebug as usize } #[cfg(feature = "profiling")] @@ -103,12 +112,14 @@ impl KernelScheme for DebugScheme { *handles.get(&id).ok_or(Error::new(EBADF))? }; - if handle.num == !0 - 1 { + if handle.num == SpecialFds::NoPreserve as usize + && handle.num == SpecialFds::DisableGraphicalDebug as usize + { return Err(Error::new(EINVAL)); } #[cfg(feature = "profiling")] - if handle.num != !0 { + if handle.num != SpecialFds::Default as usize { return crate::profiling::drain_buffer( crate::cpu_set::LogicalCpuId::new(handle.num as u32), buf, @@ -129,7 +140,9 @@ impl KernelScheme for DebugScheme { let handles = HANDLES.read(); *handles.get(&id).ok_or(Error::new(EBADF))? }; - if handle.num != !0 { + if handle.num != SpecialFds::Default as usize + && handle.num != SpecialFds::NoPreserve as usize + { return Err(Error::new(EINVAL)); } @@ -142,7 +155,7 @@ impl KernelScheme for DebugScheme { // The reason why a new writer is created for each iteration, is because the page fault // handler in usercopy might use the same lock when printing for debug purposes, and // although it most likely won't, it would be dangerous to rely on that assumption. - Writer::new().write(tmp_bytes); + Writer::new().write(tmp_bytes, handle.num != SpecialFds::NoPreserve as usize); } Ok(buf.len()) @@ -152,7 +165,9 @@ impl KernelScheme for DebugScheme { let handles = HANDLES.read(); *handles.get(&id).ok_or(Error::new(EBADF))? }; - if handle.num != !0 { + if handle.num != SpecialFds::Default as usize + && handle.num != SpecialFds::NoPreserve as usize + { return Err(Error::new(EINVAL)); }