mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-07-26 20:03:54 -06:00
rust/qemu-api: Add initial logging support based on C API
A log_mask_ln!() macro is provided which expects similar arguments as the C version. However, the formatting works as one would expect from Rust. To maximize code reuse the macro is just a thin wrapper around qemu_log(). Also, just the bare minimum of logging masks is provided which should suffice for the current use case of Rust in QEMU. Signed-off-by: Bernhard Beschow <shentey@gmail.com> Link: https://lore.kernel.org/r/20250615112037.11992-2-shentey@gmail.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
1ae4ca0463
commit
ab81002252
6 changed files with 80 additions and 0 deletions
|
@ -162,6 +162,7 @@ module status
|
||||||
``errno`` complete
|
``errno`` complete
|
||||||
``error`` stable
|
``error`` stable
|
||||||
``irq`` complete
|
``irq`` complete
|
||||||
|
``log`` proof of concept
|
||||||
``memory`` stable
|
``memory`` stable
|
||||||
``module`` complete
|
``module`` complete
|
||||||
``qdev`` stable
|
``qdev`` stable
|
||||||
|
|
|
@ -62,6 +62,7 @@ _qemu_api_rs = static_library(
|
||||||
'src/errno.rs',
|
'src/errno.rs',
|
||||||
'src/error.rs',
|
'src/error.rs',
|
||||||
'src/irq.rs',
|
'src/irq.rs',
|
||||||
|
'src/log.rs',
|
||||||
'src/memory.rs',
|
'src/memory.rs',
|
||||||
'src/module.rs',
|
'src/module.rs',
|
||||||
'src/prelude.rs',
|
'src/prelude.rs',
|
||||||
|
|
|
@ -21,6 +21,7 @@ pub mod chardev;
|
||||||
pub mod errno;
|
pub mod errno;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod irq;
|
pub mod irq;
|
||||||
|
pub mod log;
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
pub mod module;
|
pub mod module;
|
||||||
pub mod qdev;
|
pub mod qdev;
|
||||||
|
|
73
rust/qemu-api/src/log.rs
Normal file
73
rust/qemu-api/src/log.rs
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
// Copyright 2025 Bernhard Beschow <shentey@gmail.com>
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
//! Bindings for QEMU's logging infrastructure
|
||||||
|
|
||||||
|
#[repr(u32)]
|
||||||
|
/// Represents specific error categories within QEMU's logging system.
|
||||||
|
///
|
||||||
|
/// The `Log` enum provides a Rust abstraction for logging errors, corresponding
|
||||||
|
/// to a subset of the error categories defined in the C implementation.
|
||||||
|
pub enum Log {
|
||||||
|
/// Log invalid access caused by the guest.
|
||||||
|
/// Corresponds to `LOG_GUEST_ERROR` in the C implementation.
|
||||||
|
GuestError = crate::bindings::LOG_GUEST_ERROR,
|
||||||
|
|
||||||
|
/// Log guest access of unimplemented functionality.
|
||||||
|
/// Corresponds to `LOG_UNIMP` in the C implementation.
|
||||||
|
Unimp = crate::bindings::LOG_UNIMP,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A macro to log messages conditionally based on a provided mask.
|
||||||
|
///
|
||||||
|
/// The `log_mask_ln` macro checks whether the given mask matches the current
|
||||||
|
/// log level and, if so, formats and logs the message. It is the Rust
|
||||||
|
/// counterpart of the `qemu_log_mask()` macro in the C implementation.
|
||||||
|
///
|
||||||
|
/// # Parameters
|
||||||
|
///
|
||||||
|
/// - `$mask`: A log level mask. This should be a variant of the `Log` enum.
|
||||||
|
/// - `$fmt`: A format string following the syntax and rules of the `format!`
|
||||||
|
/// macro. It specifies the structure of the log message.
|
||||||
|
/// - `$args`: Optional arguments to be interpolated into the format string.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use qemu_api::{log::Log, log_mask_ln};
|
||||||
|
///
|
||||||
|
/// let error_address = 0xbad;
|
||||||
|
/// log_mask_ln!(Log::GuestError, "Address 0x{error_address:x} out of range");
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// It is also possible to use printf-style formatting, as well as having a
|
||||||
|
/// trailing `,`:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use qemu_api::{log::Log, log_mask_ln};
|
||||||
|
///
|
||||||
|
/// let error_address = 0xbad;
|
||||||
|
/// log_mask_ln!(
|
||||||
|
/// Log::GuestError,
|
||||||
|
/// "Address 0x{:x} out of range",
|
||||||
|
/// error_address,
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! log_mask_ln {
|
||||||
|
($mask:expr, $fmt:tt $($args:tt)*) => {{
|
||||||
|
// Type assertion to enforce type `Log` for $mask
|
||||||
|
let _: Log = $mask;
|
||||||
|
|
||||||
|
if unsafe {
|
||||||
|
(::qemu_api::bindings::qemu_loglevel & ($mask as std::os::raw::c_int)) != 0
|
||||||
|
} {
|
||||||
|
let formatted_string = format!("{}\n", format_args!($fmt $($args)*));
|
||||||
|
let c_string = std::ffi::CString::new(formatted_string).unwrap();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
::qemu_api::bindings::qemu_log(c_string.as_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
}
|
|
@ -11,6 +11,8 @@ pub use crate::cell::BqlRefCell;
|
||||||
|
|
||||||
pub use crate::errno;
|
pub use crate::errno;
|
||||||
|
|
||||||
|
pub use crate::log_mask_ln;
|
||||||
|
|
||||||
pub use crate::qdev::DeviceMethods;
|
pub use crate::qdev::DeviceMethods;
|
||||||
|
|
||||||
pub use crate::qom::InterfaceType;
|
pub use crate::qom::InterfaceType;
|
||||||
|
|
|
@ -48,6 +48,8 @@ typedef enum memory_order {
|
||||||
#endif /* __CLANG_STDATOMIC_H */
|
#endif /* __CLANG_STDATOMIC_H */
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
|
#include "qemu/log.h"
|
||||||
|
#include "qemu/log-for-trace.h"
|
||||||
#include "qemu/module.h"
|
#include "qemu/module.h"
|
||||||
#include "qemu-io.h"
|
#include "qemu-io.h"
|
||||||
#include "system/system.h"
|
#include "system/system.h"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue