updated
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
use anyhow::{Result, anyhow};
|
||||
use anyhow::{Result, anyhow, Context};
|
||||
use std::path::{Path};
|
||||
use std::fs;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::sync::Mutex;
|
||||
use std::sync::{Mutex, Arc};
|
||||
use tracing::{debug, warn, info};
|
||||
|
||||
use crate::sal::traits::{SensorBus, ActuatorBus, EnvironmentGuard, HardwareWatchdog, PreflightAuditor, AuditStep, AuditError, SafetyStatus, EnvironmentCtx};
|
||||
use crate::sal::safety::{TdpLimitMicroWatts, FanSpeedPercentage};
|
||||
use crate::sal::safety::{PowerLimitWatts, FanSpeedPercent};
|
||||
use crate::sal::heuristic::discovery::SystemFactSheet;
|
||||
use crate::sal::heuristic::schema::HardwareDb;
|
||||
|
||||
@@ -13,14 +14,9 @@ pub struct GenericLinuxSal {
|
||||
ctx: EnvironmentCtx,
|
||||
fact_sheet: SystemFactSheet,
|
||||
db: HardwareDb,
|
||||
suppressed_services: Mutex<Vec<String>>,
|
||||
last_valid_temp: Mutex<(f32, Instant)>,
|
||||
current_pl1: Mutex<u64>,
|
||||
last_energy: Mutex<(u64, Instant)>,
|
||||
|
||||
// --- Original State for Restoration ---
|
||||
original_pl1: Mutex<Option<u64>>,
|
||||
original_pl2: Mutex<Option<u64>>,
|
||||
}
|
||||
|
||||
impl GenericLinuxSal {
|
||||
@@ -33,14 +29,11 @@ impl GenericLinuxSal {
|
||||
|
||||
Self {
|
||||
db,
|
||||
suppressed_services: Mutex::new(Vec::new()),
|
||||
last_valid_temp: Mutex::new((0.0, Instant::now())),
|
||||
current_pl1: Mutex::new(15_000_000),
|
||||
last_energy: Mutex::new((initial_energy, Instant::now())),
|
||||
fact_sheet: facts,
|
||||
ctx,
|
||||
original_pl1: Mutex::new(None),
|
||||
original_pl2: Mutex::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +128,6 @@ impl SensorBus for GenericLinuxSal {
|
||||
}
|
||||
|
||||
fn get_throttling_status(&self) -> Result<bool> {
|
||||
// Fallback: check if any cooling device is active (cur_state > 0)
|
||||
let cooling_base = self.ctx.sysfs_base.join("sys/class/thermal");
|
||||
if let Ok(entries) = fs::read_dir(cooling_base) {
|
||||
for entry in entries.flatten() {
|
||||
@@ -168,68 +160,37 @@ impl ActuatorBus for GenericLinuxSal {
|
||||
} else { Ok(()) }
|
||||
}
|
||||
|
||||
fn set_fan_speed(&self, _speed: FanSpeedPercentage) -> Result<()> {
|
||||
fn set_fan_speed(&self, _speed: FanSpeedPercent) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_sustained_power_limit(&self, limit: TdpLimitMicroWatts) -> Result<()> {
|
||||
let rapl_path = self.fact_sheet.rapl_paths.first().ok_or_else(|| anyhow!("No PL1 path"))?;
|
||||
fs::write(rapl_path.join("constraint_0_power_limit_uw"), limit.as_u64().to_string())?;
|
||||
*self.current_pl1.lock().unwrap() = limit.as_u64();
|
||||
fn set_sustained_power_limit(&self, limit: PowerLimitWatts) -> Result<()> {
|
||||
for rapl_path in &self.fact_sheet.rapl_paths {
|
||||
let limit_path = rapl_path.join("constraint_0_power_limit_uw");
|
||||
let enable_path = rapl_path.join("constraint_0_enabled");
|
||||
fs::write(&limit_path, limit.as_microwatts().to_string())
|
||||
.with_context(|| format!("Failed to write PL1 to {:?}", limit_path))?;
|
||||
let _ = fs::write(&enable_path, "1");
|
||||
}
|
||||
*self.current_pl1.lock().unwrap() = limit.as_microwatts();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_burst_power_limit(&self, limit: TdpLimitMicroWatts) -> Result<()> {
|
||||
let rapl_path = self.fact_sheet.rapl_paths.first().ok_or_else(|| anyhow!("No PL2 path"))?;
|
||||
fs::write(rapl_path.join("constraint_1_power_limit_uw"), limit.as_u64().to_string())?;
|
||||
fn set_burst_power_limit(&self, limit: PowerLimitWatts) -> Result<()> {
|
||||
for rapl_path in &self.fact_sheet.rapl_paths {
|
||||
let limit_path = rapl_path.join("constraint_1_power_limit_uw");
|
||||
let enable_path = rapl_path.join("constraint_1_enabled");
|
||||
fs::write(&limit_path, limit.as_microwatts().to_string())
|
||||
.with_context(|| format!("Failed to write PL2 to {:?}", limit_path))?;
|
||||
let _ = fs::write(&enable_path, "1");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl EnvironmentGuard for GenericLinuxSal {
|
||||
fn suppress(&self) -> Result<()> {
|
||||
// Snapshot Power Limits
|
||||
if let Some(rapl_path) = self.fact_sheet.rapl_paths.first() {
|
||||
if let Ok(pl1) = fs::read_to_string(rapl_path.join("constraint_0_power_limit_uw")) {
|
||||
*self.original_pl1.lock().unwrap() = pl1.trim().parse().ok();
|
||||
}
|
||||
if let Ok(pl2) = fs::read_to_string(rapl_path.join("constraint_1_power_limit_uw")) {
|
||||
*self.original_pl2.lock().unwrap() = pl2.trim().parse().ok();
|
||||
}
|
||||
}
|
||||
|
||||
let mut suppressed = self.suppressed_services.lock().unwrap();
|
||||
for conflict_id in &self.fact_sheet.active_conflicts {
|
||||
if let Some(conflict) = self.db.conflicts.iter().find(|c| &c.id == conflict_id) {
|
||||
for service in &conflict.services {
|
||||
if self.ctx.runner.run("systemctl", &["is-active", "--quiet", service]).is_ok() {
|
||||
let _ = self.ctx.runner.run("systemctl", &["stop", service]);
|
||||
suppressed.push(service.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn restore(&self) -> Result<()> {
|
||||
// Restore Power Limits
|
||||
if let Some(rapl_path) = self.fact_sheet.rapl_paths.first() {
|
||||
if let Some(pl1) = *self.original_pl1.lock().unwrap() {
|
||||
let _ = fs::write(rapl_path.join("constraint_0_power_limit_uw"), pl1.to_string());
|
||||
}
|
||||
if let Some(pl2) = *self.original_pl2.lock().unwrap() {
|
||||
let _ = fs::write(rapl_path.join("constraint_1_power_limit_uw"), pl2.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
let mut suppressed = self.suppressed_services.lock().unwrap();
|
||||
for service in suppressed.drain(..) {
|
||||
let _ = self.ctx.runner.run("systemctl", &["start", &service]);
|
||||
}
|
||||
if self.is_dell() { let _ = self.set_fan_mode("auto"); }
|
||||
Ok(())
|
||||
}
|
||||
fn suppress(&self) -> Result<()> { Ok(()) }
|
||||
fn restore(&self) -> Result<()> { Ok(()) }
|
||||
}
|
||||
|
||||
impl HardwareWatchdog for GenericLinuxSal {
|
||||
@@ -245,7 +206,3 @@ impl HardwareWatchdog for GenericLinuxSal {
|
||||
Ok(SafetyStatus::Nominal)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for GenericLinuxSal {
|
||||
fn drop(&mut self) { let _ = self.restore(); }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user