kata-os-logger: support no logging interface connection out of a component

When a CAmkES component lacks an outbound connection to send log msgs
there will be no logger_log symbol. Use a weak ref here to handle that
without resorting to a feature or similar.

Mark logger connections as "maybe" so they are optional.

Change-Id: I6ecd939014d26a612d115741fd2ac673afa40857
GitOrigin-RevId: 0b1bf2611cbb628500cae37889c6547a996d50e9
This commit is contained in:
Sam Leffler 2022-08-25 15:36:09 -07:00
parent 326ec0d6c9
commit b099005951
10 changed files with 42 additions and 33 deletions

View File

@ -25,5 +25,5 @@ component MailboxDriver {
consumes Interrupt rtirq; consumes Interrupt rtirq;
consumes Interrupt eirq; consumes Interrupt eirq;
uses LoggerInterface logger; maybe uses LoggerInterface logger;
} }

View File

@ -20,7 +20,7 @@ import <MemoryInterface.camkes>;
component MemoryManager { component MemoryManager {
provides MemoryInterface memory; provides MemoryInterface memory;
uses LoggerInterface logger; maybe uses LoggerInterface logger;
// Enable KataOS CAmkES support. // Enable KataOS CAmkES support.
attribute int kataos = true; attribute int kataos = true;

View File

@ -16,6 +16,7 @@ import <LoggerInterface.camkes>;
import <MemoryInterface.camkes>; import <MemoryInterface.camkes>;
import <MlCoordinatorInterface.camkes>; import <MlCoordinatorInterface.camkes>;
import <SecurityCoordinatorInterface.camkes>; import <SecurityCoordinatorInterface.camkes>;
import <TimerServiceInterface.camkes>;
component MlCoordinator { component MlCoordinator {
control; control;
@ -32,7 +33,7 @@ component MlCoordinator {
dataport Buf CSR; dataport Buf CSR;
dataport Buf(0x1000000) TCM; dataport Buf(0x1000000) TCM;
uses LoggerInterface logger; maybe uses LoggerInterface logger;
uses MemoryInterface memory; uses MemoryInterface memory;
uses SecurityCoordinatorInterface security; uses SecurityCoordinatorInterface security;

View File

@ -24,7 +24,7 @@ component ProcessManager {
provides PackageManagementInterface pkg_mgmt; provides PackageManagementInterface pkg_mgmt;
provides ProcessControlInterface proc_ctrl; provides ProcessControlInterface proc_ctrl;
uses LoggerInterface logger; maybe uses LoggerInterface logger;
uses MemoryInterface memory; uses MemoryInterface memory;
uses SecurityCoordinatorInterface security; uses SecurityCoordinatorInterface security;

View File

@ -20,7 +20,7 @@ import <SDKRuntimeInterface.camkes>;
component SDKRuntime { component SDKRuntime {
provides SDKRuntimeInterface sdk_runtime; provides SDKRuntimeInterface sdk_runtime;
uses LoggerInterface logger; maybe uses LoggerInterface logger;
// Enable KataOS CAmkES support. // Enable KataOS CAmkES support.
attribute int kataos = true; attribute int kataos = true;

View File

@ -22,7 +22,7 @@ import <MailboxInterface.camkes>;
component SecurityCoordinator { component SecurityCoordinator {
provides SecurityCoordinatorInterface security; provides SecurityCoordinatorInterface security;
uses LoggerInterface logger; maybe uses LoggerInterface logger;
uses MemoryInterface memory; uses MemoryInterface memory;
uses MailboxAPI mailbox_api; uses MailboxAPI mailbox_api;

View File

@ -21,7 +21,7 @@ import <StorageInterface.camkes>;
component StorageManager { component StorageManager {
provides StorageInterface storage; provides StorageInterface storage;
uses LoggerInterface logger; maybe uses LoggerInterface logger;
uses SecurityCoordinatorInterface security; uses SecurityCoordinatorInterface security;
// Enable KataOS CAmkES support. // Enable KataOS CAmkES support.

View File

@ -20,7 +20,7 @@ component TimerService {
dataport Buf csr; dataport Buf csr;
consumes Interrupt timer_interrupt; consumes Interrupt timer_interrupt;
uses LoggerInterface logger; maybe uses LoggerInterface logger;
// Enable KataOS CAmkES support. // Enable KataOS CAmkES support.
attribute int kataos = true; attribute int kataos = true;

View File

@ -8,4 +8,4 @@ arrayvec = { version = "0.7", default-features = false }
core2 = { version = "0.3", default-features = false } core2 = { version = "0.3", default-features = false }
# Disable default so we don't pull in CString which requires an allocator # Disable default so we don't pull in CString which requires an allocator
cstr_core = { version = "0.2.3", default-features = false } cstr_core = { version = "0.2.3", default-features = false }
log = "0.4" log = { version = "0.4" }

View File

@ -13,6 +13,14 @@
// limitations under the License. // limitations under the License.
#![cfg_attr(not(test), no_std)] #![cfg_attr(not(test), no_std)]
#![feature(linkage)]
extern "C" {
// NB: components may not have a logging connection in which case
// logger_log will be undefined/null.
#[linkage = "extern_weak"]
static logger_log: *const ();
}
use core2::io::{Cursor, Write}; use core2::io::{Cursor, Write};
use cstr_core::CStr; use cstr_core::CStr;
@ -28,10 +36,12 @@ impl log::Log for KataLogger {
fn enabled(&self, _metadata: &Metadata) -> bool { true } fn enabled(&self, _metadata: &Metadata) -> bool { true }
fn log(&self, record: &Record) { fn log(&self, record: &Record) {
if self.enabled(record.metadata()) { let typed_logger_log: Option<extern "C" fn(level: u8, msg: *const u8)> =
extern "C" { unsafe { core::mem::transmute(logger_log) };
fn logger_log(level: u8, msg: *const cstr_core::c_char); if typed_logger_log.is_none() {
return;
} }
if self.enabled(record.metadata()) {
let mut buf = [0 as u8; MAX_MSG_LEN]; let mut buf = [0 as u8; MAX_MSG_LEN];
let mut cur = Cursor::new(&mut buf[..]); let mut cur = Cursor::new(&mut buf[..]);
// Log msgs are of the form: '<target>::<fmt'd-msg> // Log msgs are of the form: '<target>::<fmt'd-msg>
@ -41,7 +51,6 @@ impl log::Log for KataLogger {
cur.write(b"...\0").expect("write!"); cur.write(b"...\0").expect("write!");
() ()
}); });
unsafe {
// If an embedded nul is identified, replace the message; there // If an embedded nul is identified, replace the message; there
// are likely better solutions but this should not happen. // are likely better solutions but this should not happen.
fn embedded_nul_cstr<'a>( fn embedded_nul_cstr<'a>(
@ -55,7 +64,7 @@ impl log::Log for KataLogger {
} }
// NB: this releases the ref on buf held by the Cursor // NB: this releases the ref on buf held by the Cursor
let pos = cur.position() as usize; let pos = cur.position() as usize;
logger_log( (typed_logger_log.unwrap())(
record.level() as u8, record.level() as u8,
match CStr::from_bytes_with_nul(&buf[..pos]) { match CStr::from_bytes_with_nul(&buf[..pos]) {
Ok(cstr) => cstr, Ok(cstr) => cstr,
@ -65,7 +74,6 @@ impl log::Log for KataLogger {
); );
} }
} }
}
fn flush(&self) {} fn flush(&self) {}
} }