Skip to content

Commit 3339b17

Browse files
authored
[RSDK-9548] log storage usage on startup (#365)
1 parent c4704a7 commit 3339b17

3 files changed

Lines changed: 70 additions & 9 deletions

File tree

micro-rdk/src/common/conn/viam.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use std::future::Future;
1313
use crate::common::app_client::{
1414
AppClient, AppClientBuilder, AppClientError, PeriodicAppClientTask,
1515
};
16-
use crate::common::credentials_storage::TlsCertificate;
16+
use crate::common::credentials_storage::{StorageDiagnostic, TlsCertificate};
1717
use crate::common::webrtc::signaling_server::SignalingServer;
1818
use std::marker::PhantomData;
1919
use std::net::{SocketAddr, TcpListener};
@@ -91,23 +91,33 @@ impl From<&proto::app::v1::CloudConfig> for RobotCloudConfig {
9191

9292
#[cfg(not(feature = "ota"))]
9393
pub trait ViamServerStorage:
94-
RobotConfigurationStorage + WifiCredentialStorage + Clone + 'static
94+
RobotConfigurationStorage + WifiCredentialStorage + StorageDiagnostic + Clone + 'static
9595
{
9696
}
9797
#[cfg(not(feature = "ota"))]
9898
impl<T> ViamServerStorage for T where
99-
T: RobotConfigurationStorage + WifiCredentialStorage + Clone + 'static
99+
T: RobotConfigurationStorage + WifiCredentialStorage + StorageDiagnostic + Clone + 'static
100100
{
101101
}
102102

103103
#[cfg(feature = "ota")]
104104
pub trait ViamServerStorage:
105-
RobotConfigurationStorage + WifiCredentialStorage + OtaMetadataStorage + Clone + 'static
105+
RobotConfigurationStorage
106+
+ WifiCredentialStorage
107+
+ OtaMetadataStorage
108+
+ StorageDiagnostic
109+
+ Clone
110+
+ 'static
106111
{
107112
}
108113
#[cfg(feature = "ota")]
109114
impl<T> ViamServerStorage for T where
110-
T: RobotConfigurationStorage + WifiCredentialStorage + OtaMetadataStorage + Clone + 'static
115+
T: RobotConfigurationStorage
116+
+ WifiCredentialStorage
117+
+ OtaMetadataStorage
118+
+ StorageDiagnostic
119+
+ Clone
120+
+ 'static
111121
{
112122
}
113123

@@ -454,6 +464,7 @@ where
454464
}
455465

456466
pub(crate) async fn run(&mut self) -> ! {
467+
self.storage.log_space_diagnostic();
457468
// The first step is to check whether or not credentials are populated in
458469
// storage. If not, we should go straight to provisioning.
459470
//
@@ -643,6 +654,7 @@ where
643654
})
644655
.ok()
645656
} else {
657+
log::info!("Failed to obtain certificates from app, will attempt to load any stored certificates");
646658
Some(self.storage.get_tls_certificate().ok())
647659
}
648660
.flatten();
@@ -664,6 +676,8 @@ where
664676
}
665677
}
666678

679+
self.storage.log_space_diagnostic();
680+
667681
let (tx, rx) = async_channel::bounded(1);
668682

669683
let mut inner = RobotServer {

micro-rdk/src/common/credentials_storage.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@ pub trait OtaMetadataStorage {
139139
fn reset_ota_metadata(&self) -> Result<(), Self::Error>;
140140
}
141141

142+
pub trait StorageDiagnostic {
143+
fn log_space_diagnostic(&self);
144+
}
145+
142146
#[derive(Default)]
143147
struct RAMCredentialStorageInner {
144148
robot_creds: Option<RobotCredentials>,
@@ -300,6 +304,10 @@ impl WifiCredentialStorage for RAMStorage {
300304
}
301305
}
302306

307+
impl StorageDiagnostic for RAMStorage {
308+
fn log_space_diagnostic(&self) {}
309+
}
310+
303311
impl From<Infallible> for ServerError {
304312
fn from(_: Infallible) -> Self {
305313
unreachable!()

micro-rdk/src/esp32/nvs_storage.rs

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22
use bytes::Bytes;
33
use hyper::{http::uri::InvalidUri, Uri};
44
use prost::{DecodeError, Message};
5-
use std::{cell::RefCell, rc::Rc};
5+
use std::{cell::RefCell, ffi::CString, num::NonZeroI32, rc::Rc};
66
use thiserror::Error;
77

88
use crate::{
99
common::{
1010
credentials_storage::{
11-
RobotConfigurationStorage, RobotCredentials, TlsCertificate, WifiCredentialStorage,
12-
WifiCredentials,
11+
RobotConfigurationStorage, RobotCredentials, StorageDiagnostic, TlsCertificate,
12+
WifiCredentialStorage, WifiCredentials,
1313
},
1414
grpc::{GrpcError, ServerError},
1515
},
1616
esp32::esp_idf_svc::{
1717
nvs::{EspCustomNvs, EspCustomNvsPartition, EspNvs},
18-
sys::EspError,
18+
sys::{esp, nvs_get_stats, nvs_stats_t, EspError, ESP_ERR_INVALID_ARG},
1919
},
2020
proto::{app::v1::RobotConfig, provisioning::v1::CloudConfig},
2121
};
@@ -41,6 +41,7 @@ pub struct NVSStorage {
4141
// esp-idf-svc partition driver ensures that only one handle of a type can be created
4242
// so inner mutability can be achieves safely with RefCell
4343
nvs: Rc<RefCell<EspCustomNvs>>,
44+
partition_name: CString,
4445
}
4546

4647
impl NVSStorage {
@@ -51,6 +52,9 @@ impl NVSStorage {
5152

5253
Ok(Self {
5354
nvs: Rc::new(nvs.into()),
55+
partition_name: CString::new(partition_name).map_err(|_| {
56+
EspError::from_non_zero(NonZeroI32::new(ESP_ERR_INVALID_ARG).unwrap())
57+
})?,
5458
})
5559
}
5660

@@ -126,6 +130,41 @@ impl NVSStorage {
126130
}
127131
}
128132

133+
const BYTES_PER_ENTRY: usize = 32;
134+
135+
impl StorageDiagnostic for NVSStorage {
136+
fn log_space_diagnostic(&self) {
137+
let mut stats: nvs_stats_t = Default::default();
138+
if let Err(err) =
139+
esp!(unsafe { nvs_get_stats(self.partition_name.as_ptr(), &mut stats as *mut _) })
140+
{
141+
log::error!("could not acquire NVS stats: {:?}", err);
142+
return;
143+
}
144+
145+
let used_entries = stats.used_entries;
146+
let used_space = used_entries * BYTES_PER_ENTRY;
147+
let total_space = stats.total_entries * BYTES_PER_ENTRY;
148+
149+
// From experimentation we have found that NVS requires 4000 bytes of
150+
// unused space for reasons unknown. The percentage portion of the calculation (0.976)
151+
// comes from the blob size restriction as stated in the ESP32 documentation
152+
// on NVS
153+
let total_usable_space = (0.976 * (total_space as f64)) - 4000.0;
154+
let fraction_used = (used_space as f64) / total_usable_space;
155+
log::log!(
156+
if fraction_used > 0.9 {
157+
log::Level::Warn
158+
} else {
159+
log::Level::Info
160+
},
161+
"NVS stats: {:?} bytes used of {:?} available",
162+
used_space,
163+
total_space
164+
);
165+
}
166+
}
167+
129168
const NVS_ROBOT_SECRET_KEY: &str = "ROBOT_SECRET";
130169
const NVS_ROBOT_ID_KEY: &str = "ROBOT_ID";
131170
const NVS_ROBOT_APP_ADDRESS: &str = "ROBOT_APP_ADDR";

0 commit comments

Comments
 (0)