mirror of
https://gitlab.steamos.cloud/holo/steamos-manager.git
synced 2025-07-08 07:30:36 -04:00
hardware: Let fan control be configured and disabled
This commit is contained in:
parent
92235d0f47
commit
7dc0d0969d
4 changed files with 94 additions and 16 deletions
|
@ -16,3 +16,6 @@ script = "/usr/lib/hwsupport/format-device.sh"
|
||||||
label_flag = "--label"
|
label_flag = "--label"
|
||||||
device_flag = "--device"
|
device_flag = "--device"
|
||||||
no_validate_flag = "--skip-validation"
|
no_validate_flag = "--skip-validation"
|
||||||
|
|
||||||
|
[fan_control]
|
||||||
|
systemd = "jupiter-fan-control.service"
|
||||||
|
|
|
@ -5,14 +5,15 @@
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, Error, Result};
|
use anyhow::{anyhow, bail, ensure, Error, Result};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
use zbus::Connection;
|
use zbus::Connection;
|
||||||
|
|
||||||
use crate::path;
|
use crate::path;
|
||||||
use crate::process::script_exit_code;
|
use crate::platform::{platform_config, ServiceConfig};
|
||||||
|
use crate::process::{run_script, script_exit_code};
|
||||||
use crate::systemd::SystemdUnit;
|
use crate::systemd::SystemdUnit;
|
||||||
|
|
||||||
const BOARD_VENDOR_PATH: &str = "/sys/class/dmi/id/board_vendor";
|
const BOARD_VENDOR_PATH: &str = "/sys/class/dmi/id/board_vendor";
|
||||||
|
@ -148,30 +149,66 @@ impl FanControl {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_state(&self) -> Result<FanControlState> {
|
pub async fn get_state(&self) -> Result<FanControlState> {
|
||||||
|
let config = platform_config().await?;
|
||||||
|
match config
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|config| config.fan_control.as_ref())
|
||||||
|
{
|
||||||
|
Some(ServiceConfig::Systemd(service)) => {
|
||||||
let jupiter_fan_control =
|
let jupiter_fan_control =
|
||||||
SystemdUnit::new(self.connection.clone(), "jupiter-fan-control.service").await?;
|
SystemdUnit::new(self.connection.clone(), service).await?;
|
||||||
let active = jupiter_fan_control.active().await?;
|
let active = jupiter_fan_control.active().await?;
|
||||||
Ok(match active {
|
Ok(match active {
|
||||||
true => FanControlState::Os,
|
true => FanControlState::Os,
|
||||||
false => FanControlState::Bios,
|
false => FanControlState::Bios,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Some(ServiceConfig::Script {
|
||||||
|
start: _,
|
||||||
|
stop: _,
|
||||||
|
status,
|
||||||
|
}) => {
|
||||||
|
let res = script_exit_code(&status.script, &status.script_args).await?;
|
||||||
|
ensure!(res >= 0, "Script exited abnormally");
|
||||||
|
FanControlState::try_from(res as u32)
|
||||||
|
}
|
||||||
|
None => bail!("Fan control not configured"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn set_state(&self, state: FanControlState) -> Result<()> {
|
pub async fn set_state(&self, state: FanControlState) -> Result<()> {
|
||||||
// Run what steamos-polkit-helpers/jupiter-fan-control does
|
// Run what steamos-polkit-helpers/jupiter-fan-control does
|
||||||
|
let config = platform_config().await?;
|
||||||
|
match config
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|config| config.fan_control.as_ref())
|
||||||
|
{
|
||||||
|
Some(ServiceConfig::Systemd(service)) => {
|
||||||
let jupiter_fan_control =
|
let jupiter_fan_control =
|
||||||
SystemdUnit::new(self.connection.clone(), "jupiter-fan-control.service").await?;
|
SystemdUnit::new(self.connection.clone(), service).await?;
|
||||||
match state {
|
match state {
|
||||||
FanControlState::Os => jupiter_fan_control.start().await,
|
FanControlState::Os => jupiter_fan_control.start().await,
|
||||||
FanControlState::Bios => jupiter_fan_control.stop().await,
|
FanControlState::Bios => jupiter_fan_control.stop().await,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some(ServiceConfig::Script {
|
||||||
|
start,
|
||||||
|
stop,
|
||||||
|
status: _,
|
||||||
|
}) => match state {
|
||||||
|
FanControlState::Os => run_script(&start.script, &start.script_args).await,
|
||||||
|
FanControlState::Bios => run_script(&stop.script, &stop.script_args).await,
|
||||||
|
},
|
||||||
|
None => bail!("Fan control not configured"),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod test {
|
pub mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::error::to_zbus_fdo_error;
|
use crate::error::to_zbus_fdo_error;
|
||||||
|
use crate::platform::{PlatformConfig, ServiceConfig};
|
||||||
use crate::{enum_roundtrip, testing};
|
use crate::{enum_roundtrip, testing};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio::fs::{create_dir_all, write};
|
use tokio::fs::{create_dir_all, write};
|
||||||
|
@ -322,6 +359,16 @@ pub mod test {
|
||||||
|
|
||||||
sleep(Duration::from_millis(10)).await;
|
sleep(Duration::from_millis(10)).await;
|
||||||
|
|
||||||
|
h.test.platform_config.replace(Some(PlatformConfig {
|
||||||
|
factory_reset: None,
|
||||||
|
update_bios: None,
|
||||||
|
update_dock: None,
|
||||||
|
storage: None,
|
||||||
|
fan_control: Some(ServiceConfig::Systemd(String::from(
|
||||||
|
"jupiter-fan-control.service",
|
||||||
|
))),
|
||||||
|
}));
|
||||||
|
|
||||||
let fan_control = FanControl::new(connection);
|
let fan_control = FanControl::new(connection);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
fan_control.get_state().await.unwrap(),
|
fan_control.get_state().await.unwrap(),
|
||||||
|
|
|
@ -582,7 +582,12 @@ pub(crate) async fn create_interfaces(
|
||||||
object_server.at(MANAGER_PATH, factory_reset).await?;
|
object_server.at(MANAGER_PATH, factory_reset).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|config| config.fan_control.is_some())
|
||||||
|
{
|
||||||
object_server.at(MANAGER_PATH, fan_control).await?;
|
object_server.at(MANAGER_PATH, fan_control).await?;
|
||||||
|
}
|
||||||
|
|
||||||
if !get_available_gpu_performance_levels()
|
if !get_available_gpu_performance_levels()
|
||||||
.await
|
.await
|
||||||
|
@ -645,7 +650,7 @@ mod test {
|
||||||
use crate::daemon::user::UserContext;
|
use crate::daemon::user::UserContext;
|
||||||
use crate::hardware::test::fake_model;
|
use crate::hardware::test::fake_model;
|
||||||
use crate::hardware::HardwareVariant;
|
use crate::hardware::HardwareVariant;
|
||||||
use crate::platform::{PlatformConfig, ScriptConfig, StorageConfig};
|
use crate::platform::{PlatformConfig, ScriptConfig, ServiceConfig, StorageConfig};
|
||||||
use crate::{power, testing};
|
use crate::{power, testing};
|
||||||
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
@ -664,6 +669,9 @@ mod test {
|
||||||
update_bios: Some(ScriptConfig::default()),
|
update_bios: Some(ScriptConfig::default()),
|
||||||
update_dock: Some(ScriptConfig::default()),
|
update_dock: Some(ScriptConfig::default()),
|
||||||
storage: Some(StorageConfig::default()),
|
storage: Some(StorageConfig::default()),
|
||||||
|
fan_control: Some(ServiceConfig::Systemd(String::from(
|
||||||
|
"jupiter-fan-control.service",
|
||||||
|
))),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -767,6 +775,13 @@ mod test {
|
||||||
.unwrap());
|
.unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn interface_missing_fan_control1() {
|
||||||
|
let test = start(None).await.expect("start");
|
||||||
|
|
||||||
|
assert!(test_interface_missing::<FanControl1>(&test.connection).await);
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn interface_matches_gpu_performance_level1() {
|
async fn interface_matches_gpu_performance_level1() {
|
||||||
let test = start(all_config()).await.expect("start");
|
let test = start(all_config()).await.expect("start");
|
||||||
|
|
|
@ -25,6 +25,7 @@ pub(crate) struct PlatformConfig {
|
||||||
pub update_bios: Option<ScriptConfig>,
|
pub update_bios: Option<ScriptConfig>,
|
||||||
pub update_dock: Option<ScriptConfig>,
|
pub update_dock: Option<ScriptConfig>,
|
||||||
pub storage: Option<StorageConfig>,
|
pub storage: Option<StorageConfig>,
|
||||||
|
pub fan_control: Option<ServiceConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default, Deserialize, Debug)]
|
#[derive(Clone, Default, Deserialize, Debug)]
|
||||||
|
@ -34,6 +35,18 @@ pub(crate) struct ScriptConfig {
|
||||||
pub script_args: Vec<String>,
|
pub script_args: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Deserialize, Debug)]
|
||||||
|
pub(crate) enum ServiceConfig {
|
||||||
|
#[serde(rename = "systemd")]
|
||||||
|
Systemd(String),
|
||||||
|
#[serde(rename = "script")]
|
||||||
|
Script {
|
||||||
|
start: ScriptConfig,
|
||||||
|
stop: ScriptConfig,
|
||||||
|
status: ScriptConfig,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default, Deserialize, Debug)]
|
#[derive(Clone, Default, Deserialize, Debug)]
|
||||||
pub(crate) struct StorageConfig {
|
pub(crate) struct StorageConfig {
|
||||||
pub trim_devices: ScriptConfig,
|
pub trim_devices: ScriptConfig,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue