If I run the below hermit os based app with firecracker it prints out:
SystemTime UNIX epoch: 943920000.015268000 s
SystemTime UTC date: 1999-11-30
I expected it to be something along the lines of:
SystemTime UNIX epoch: 1783697396.421537000 s
SystemTime UTC date: 2026-07-10
I used somthing like this as my firecracker.json:
{
"boot-source": {
"kernel_image_path": "<some-path-to>/hermit-loader-x86_64-linux",
"initrd_path": "target/x86_64-unknown-hermit/release/example",
"boot_args": "console=ttyS0"
},
"machine-config": {
"vcpu_count": 1,
"mem_size_mib": 64,
"smt": false
},
"drives": []
}
And launched it with:
$ firecracker --no-api --config-file firecracker.json
Running it in qemu produces the expected outuput. The root cause is that Firecracker (and other minimal microVM monitors) expose no CMOS RTC, so Hermit's RTC-based boot clock reads garbage and lands in ~1999. The main reason this is an issue for me where this actually came up is that it breaks anything that validates certificate/token validity windows inside the guest.
#[cfg(target_os = "hermit")]
use hermit as _;
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
use time::OffsetDateTime;
fn main() {
println!("booted");
match SystemTime::now().duration_since(UNIX_EPOCH) {
Ok(dur) => {
println!(
"SystemTime UNIX epoch: {}.{:09} s",
dur.as_secs(),
dur.subsec_nanos(),
);
match OffsetDateTime::from_unix_timestamp(dur.as_secs() as i64) {
Ok(dt) => println!(
"SystemTime UTC date: {}-{:02}-{:02}",
dt.year(),
dt.month() as u8,
dt.day(),
),
Err(e) => println!("timestamp out of range: {e}"),
}
}
Err(e) => {
// A clock before 1970 means SystemTime is uninitialised/garbage.
println!(
"SystemTime is BEFORE the UNIX epoch by {:?} \
(wall clock not set correctly)",
e.duration(),
);
}
}
}
To get around it I added code in systemtime.rs for getting the time from the kvmclock, which is what firecracker exposes. Happy to share it if you'd like!
If I run the below hermit os based app with firecracker it prints out:
I expected it to be something along the lines of:
I used somthing like this as my firecracker.json:
{ "boot-source": { "kernel_image_path": "<some-path-to>/hermit-loader-x86_64-linux", "initrd_path": "target/x86_64-unknown-hermit/release/example", "boot_args": "console=ttyS0" }, "machine-config": { "vcpu_count": 1, "mem_size_mib": 64, "smt": false }, "drives": [] }And launched it with:
Running it in qemu produces the expected outuput. The root cause is that Firecracker (and other minimal microVM monitors) expose no CMOS RTC, so Hermit's RTC-based boot clock reads garbage and lands in ~1999. The main reason this is an issue for me where this actually came up is that it breaks anything that validates certificate/token validity windows inside the guest.
To get around it I added code in
systemtime.rsfor getting the time from the kvmclock, which is what firecracker exposes. Happy to share it if you'd like!