1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
34//! This module implements the an interface to the kernel logger.
5//!
6//! Underhill_init performs no filtering of its logging messages when running in
7//! a confidential VM. This is because it runs before any keys can be accessed
8//! or any guest code is executed, and therefore it can not leak anything
9//! sensitive.
1011use std::fs::File;
12use std::fs::OpenOptions;
13use std::io;
14use std::io::Write;
1516pub struct SysLog {
17 kmsg: File,
18}
1920impl log::Log for SysLog {
21fn enabled(&self, _metadata: &log::Metadata<'_>) -> bool {
22true
23}
2425fn log(&self, record: &log::Record<'_>) {
26// Match the log levels fairly close to the kernel log level semantics.
27let level = match record.level() {
28 log::Level::Error => kmsg_defs::LOGLEVEL_ERR,
29 log::Level::Warn => kmsg_defs::LOGLEVEL_WARNING,
30 log::Level::Info => kmsg_defs::LOGLEVEL_NOTICE,
31 log::Level::Debug => kmsg_defs::LOGLEVEL_INFO,
32 log::Level::Trace => kmsg_defs::LOGLEVEL_DEBUG,
33 };
3435let n = level | (kmsg_defs::UNDERHILL_INIT_KMSG_FACILITY << 3);
3637// Construct a local buffer so that the write to /dev/kmsg happens as a
38 // single write, which is necessary to ensure that the message stays
39 // together on one line.
40let mut buf = Vec::new();
41writeln!(buf, "<{}>{}: {}", n, record.target(), record.args()).unwrap();
42let mut kmsg = &self.kmsg;
43let _ = kmsg.write(&buf);
44 }
4546fn flush(&self) {}
47}
4849impl SysLog {
50pub fn new() -> io::Result<Self> {
51Ok(Self {
52 kmsg: OpenOptions::new().write(true).open("/dev/kmsg")?,
53 })
54 }
55}