feat: login - write system log to disk (0:/os/logs/montaukos) during shutdown, limit disk flush stage to non-ramdisk storage devices
This commit is contained in:
@@ -9,6 +9,11 @@
|
||||
|
||||
using namespace gui;
|
||||
|
||||
bool volume0_is_persistent() {
|
||||
if (montauk::drivekind(0) == 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Minimum time each shutdown stage stays on screen, so the status message is
|
||||
// readable even when the underlying work completes near-instantly.
|
||||
static constexpr uint64_t STAGE_MIN_VISIBLE_MS = 600;
|
||||
@@ -23,6 +28,7 @@ static constexpr uint64_t STAGE_MIN_VISIBLE_MS = 600;
|
||||
// wedged storage controller hits this bound.
|
||||
static constexpr uint64_t BT_STAGE_TIMEOUT_MS = 4000;
|
||||
static constexpr uint64_t FS_STAGE_TIMEOUT_MS = 10000;
|
||||
static constexpr uint64_t LOG_WRITE_TIMEOUT_MS = 10000;
|
||||
|
||||
void draw_shutdown_screen(LoginState* ls, const char* heading, const char* status) {
|
||||
Framebuffer& fb = ls->fb;
|
||||
@@ -171,6 +177,39 @@ void stage_disconnect_bluetooth() {
|
||||
}
|
||||
}
|
||||
|
||||
static bool path_is_file(const char* path) {
|
||||
montauk::abi::FileStat st;
|
||||
if (montauk::stat(path, &st) < 0) return false;
|
||||
|
||||
return !st.isDir;
|
||||
}
|
||||
|
||||
#define LOG_READ_SIZE 65536
|
||||
|
||||
// Write the system log to a file on disk
|
||||
void stage_save_log() {
|
||||
// Edge case - 0:/os/logs exists and is a file
|
||||
if (path_is_file("0:/os/logs"))
|
||||
return;
|
||||
|
||||
montauk::fmkdir("0:/os/logs");
|
||||
|
||||
// Clear any existing montaukos log
|
||||
montauk::fdelete("0:/os/logs/montaukos");
|
||||
|
||||
int handle = montauk::fcreate("0:/os/logs/montaukos");
|
||||
if (handle < 0)
|
||||
return;
|
||||
|
||||
uint8_t* syslog_buf = (uint8_t*)montauk::malloc(LOG_READ_SIZE);
|
||||
int n = montauk::read_log((char *)syslog_buf, LOG_READ_SIZE);
|
||||
|
||||
int result = montauk::fwrite(handle, syslog_buf, 0, n);
|
||||
|
||||
montauk::close(handle);
|
||||
montauk::mfree(syslog_buf);
|
||||
}
|
||||
|
||||
void stage_flush_filesystems() {
|
||||
montauk::fs_sync();
|
||||
}
|
||||
@@ -193,13 +232,23 @@ void perform_graceful_shutdown(LoginState* ls, int action) {
|
||||
}
|
||||
}
|
||||
|
||||
// ==== Stage 2: flush writes and unmount filesystems ====
|
||||
show_stage(ls, heading, "Flushing file systems...");
|
||||
if (!run_stage(stage_flush_filesystems, FS_STAGE_TIMEOUT_MS)) {
|
||||
show_stage(ls, heading, "Storage is unresponsive, continuing...");
|
||||
// No need to save log files or flush to disk if volume 0 is a ramdisk anyway
|
||||
if (volume0_is_persistent()) {
|
||||
// ==== Stage 2: write system log to disk ====
|
||||
show_stage(ls, heading, "Saving system log...");
|
||||
if (!run_stage(stage_save_log, LOG_WRITE_TIMEOUT_MS)) {
|
||||
show_stage(ls, heading, "Log save is unresponsive, continuing...");
|
||||
}
|
||||
|
||||
// ==== Stage 3: flush writes and unmount filesystems ====
|
||||
show_stage(ls, heading, "Flushing file systems...");
|
||||
if (!run_stage(stage_flush_filesystems, FS_STAGE_TIMEOUT_MS)) {
|
||||
show_stage(ls, heading, "Storage is unresponsive, continuing...");
|
||||
}
|
||||
}
|
||||
|
||||
// ==== Stage 3: dispatch the ACPI power-off / reset ====
|
||||
|
||||
// ==== Stage 4: dispatch the ACPI power-off / reset ====
|
||||
show_stage(ls, heading, rebooting ? "Restarting now..." : "Powering off...");
|
||||
if (rebooting) {
|
||||
montauk::reset();
|
||||
|
||||
Reference in New Issue
Block a user