kernel/hil/log.rs
1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Interface for a persistent log that stores distinct log entries.
6//!
7//! Log entries are appended to the end of a log and read back sequentially. Log data persists
8//! across device reboots.
9
10use crate::ErrorCode;
11
12/// An interface for reading from log storage.
13pub trait LogRead<'a> {
14 /// Unique identifier for log entries.
15 type EntryID;
16
17 /// Set the client for reading from a log. The client will be called when reading operations complete.
18 fn set_read_client(&'a self, read_client: &'a dyn LogReadClient);
19
20 /// Read the next entry from the log. The log advances to the next entry after a successful
21 /// read. State does not change in the event of a failure.
22 fn read(
23 &self,
24 buffer: &'static mut [u8],
25 length: usize,
26 ) -> Result<(), (ErrorCode, &'static mut [u8])>;
27
28 /// Returns the entry ID at the start of the log. This is the ID of the oldest remaining entry.
29 fn log_start(&self) -> Self::EntryID;
30
31 /// Returns the entry ID at the end of the log. This is the ID of the next entry to be
32 /// appended.
33 fn log_end(&self) -> Self::EntryID;
34
35 /// Returns the ID of the next entry to be read.
36 fn next_read_entry_id(&self) -> Self::EntryID;
37
38 /// Seek to the entry with the given entry ID and begin reading from there. Fails without
39 /// modifying the read position if the given entry ID is invalid or no longer in the log.
40 fn seek(&self, entry: Self::EntryID) -> Result<(), ErrorCode>;
41
42 /// Get approximate log capacity in bytes.
43 fn get_size(&self) -> usize;
44}
45
46/// Receive callbacks from `LogRead`.
47pub trait LogReadClient {
48 /// Returns a buffer containing data read and the length of the number of bytes read or an error
49 /// code if the read failed.
50 fn read_done(&self, buffer: &'static mut [u8], length: usize, error: Result<(), ErrorCode>);
51
52 /// Returns whether the seek succeeded or failed.
53 fn seek_done(&self, error: Result<(), ErrorCode>);
54}
55
56/// An interface for writing to log storage.
57pub trait LogWrite<'a> {
58 /// Set the client for appending from a log. The client will be called when writing operations complete.
59 fn set_append_client(&'a self, append_client: &'a dyn LogWriteClient);
60
61 /// Append an entry to the end of the log. May fail if the entry is too large.
62 fn append(
63 &self,
64 buffer: &'static mut [u8],
65 length: usize,
66 ) -> Result<(), (ErrorCode, &'static mut [u8])>;
67
68 /// Sync log to storage, making all entries persistent (not including any entries that were
69 /// previously overwritten). There is no guarantee that any changes to the log are persistent
70 /// until it is synced. In the event of an error, not all pages may be synced, but the log will
71 /// remain in a valid state.
72 fn sync(&self) -> Result<(), ErrorCode>;
73
74 /// Erase the entire log. In the event of a failure, only some pages may be erased, but the log
75 /// will remain in a valid state.
76 fn erase(&self) -> Result<(), ErrorCode>;
77}
78
79/// Receive callbacks from `LogWrite`.
80pub trait LogWriteClient {
81 /// Returns the original buffer that contained the data to write, the number of bytes written,
82 /// and whether any old entries in the log were lost (due to a circular log being filled up).
83 fn append_done(
84 &self,
85 buffer: &'static mut [u8],
86 length: usize,
87 records_lost: bool,
88 error: Result<(), ErrorCode>,
89 );
90
91 /// Returns whether or not all pages were correctly synced, making all changes persistent.
92 fn sync_done(&self, error: Result<(), ErrorCode>);
93
94 /// Returns whether or not all pages of the log were erased.
95 fn erase_done(&self, error: Result<(), ErrorCode>);
96}