mirror of
https://gitlab.steamos.cloud/holo/steamos-manager.git
synced 2025-07-05 14:10:34 -04:00
Fix some clippy::pedantic warnings
This commit is contained in:
parent
d3152cb38d
commit
127eab4863
16 changed files with 161 additions and 166 deletions
|
@ -10,7 +10,6 @@ use clap::{Parser, Subcommand};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use std::ops::Deref;
|
|
||||||
use steamos_manager::cec::HdmiCecState;
|
use steamos_manager::cec::HdmiCecState;
|
||||||
use steamos_manager::hardware::FanControlState;
|
use steamos_manager::hardware::FanControlState;
|
||||||
use steamos_manager::power::{CPUScalingGovernor, GPUPerformanceLevel, GPUPowerProfile};
|
use steamos_manager::power::{CPUScalingGovernor, GPUPerformanceLevel, GPUPowerProfile};
|
||||||
|
@ -165,6 +164,48 @@ enum Commands {
|
||||||
FactoryReset,
|
FactoryReset,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_all_properties(conn: &Connection) -> Result<()> {
|
||||||
|
let proxy = IntrospectableProxy::builder(conn)
|
||||||
|
.destination("com.steampowered.SteamOSManager1")?
|
||||||
|
.path("/com/steampowered/SteamOSManager1")?
|
||||||
|
.build()
|
||||||
|
.await?;
|
||||||
|
let introspection = proxy.introspect().await?;
|
||||||
|
let introspection = Node::from_reader(Cursor::new(introspection))?;
|
||||||
|
|
||||||
|
let properties_proxy = PropertiesProxy::new(
|
||||||
|
&conn,
|
||||||
|
"com.steampowered.SteamOSManager1",
|
||||||
|
"/com/steampowered/SteamOSManager1",
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let mut properties = HashMap::new();
|
||||||
|
for interface in introspection.interfaces() {
|
||||||
|
let name = match interface.name() {
|
||||||
|
name if name
|
||||||
|
.as_str()
|
||||||
|
.starts_with("com.steampowered.SteamOSManager1") =>
|
||||||
|
{
|
||||||
|
name
|
||||||
|
}
|
||||||
|
_ => continue,
|
||||||
|
};
|
||||||
|
properties.extend(
|
||||||
|
properties_proxy
|
||||||
|
.get_all(zvariant::Optional::from(Some(name)))
|
||||||
|
.await?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for key in properties.keys().sorted() {
|
||||||
|
let value = &properties[key];
|
||||||
|
let val = &**value;
|
||||||
|
println!("{key}: {val}");
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_lines)]
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
// This is a command-line utility that calls api using dbus
|
// This is a command-line utility that calls api using dbus
|
||||||
|
@ -178,43 +219,7 @@ async fn main() -> Result<()> {
|
||||||
// Then process arguments
|
// Then process arguments
|
||||||
match &args.command {
|
match &args.command {
|
||||||
Commands::GetAllProperties => {
|
Commands::GetAllProperties => {
|
||||||
let proxy = IntrospectableProxy::builder(&conn)
|
get_all_properties(&conn).await?;
|
||||||
.destination("com.steampowered.SteamOSManager1")?
|
|
||||||
.path("/com/steampowered/SteamOSManager1")?
|
|
||||||
.build()
|
|
||||||
.await?;
|
|
||||||
let introspection = proxy.introspect().await?;
|
|
||||||
let introspection = Node::from_reader(Cursor::new(introspection))?;
|
|
||||||
|
|
||||||
let properties_proxy = PropertiesProxy::new(
|
|
||||||
&conn,
|
|
||||||
"com.steampowered.SteamOSManager1",
|
|
||||||
"/com/steampowered/SteamOSManager1",
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let mut properties = HashMap::new();
|
|
||||||
for interface in introspection.interfaces() {
|
|
||||||
let name = match interface.name() {
|
|
||||||
name if name
|
|
||||||
.as_str()
|
|
||||||
.starts_with("com.steampowered.SteamOSManager1") =>
|
|
||||||
{
|
|
||||||
name
|
|
||||||
}
|
|
||||||
_ => continue,
|
|
||||||
};
|
|
||||||
properties.extend(
|
|
||||||
properties_proxy
|
|
||||||
.get_all(zvariant::Optional::from(Some(name)))
|
|
||||||
.await?,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
for key in properties.keys().sorted() {
|
|
||||||
let value = &properties[key];
|
|
||||||
let val = value.deref();
|
|
||||||
println!("{key}: {val}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Commands::GetAlsCalibrationGain => {
|
Commands::GetAlsCalibrationGain => {
|
||||||
let proxy = AmbientLightSensor1Proxy::new(&conn).await?;
|
let proxy = AmbientLightSensor1Proxy::new(&conn).await?;
|
||||||
|
@ -235,7 +240,7 @@ async fn main() -> Result<()> {
|
||||||
let proxy = FanControl1Proxy::new(&conn).await?;
|
let proxy = FanControl1Proxy::new(&conn).await?;
|
||||||
let state = proxy.fan_control_state().await?;
|
let state = proxy.fan_control_state().await?;
|
||||||
match FanControlState::try_from(state) {
|
match FanControlState::try_from(state) {
|
||||||
Ok(s) => println!("Fan control state: {}", s),
|
Ok(s) => println!("Fan control state: {s}"),
|
||||||
Err(_) => println!("Got unknown value {state} from backend"),
|
Err(_) => println!("Got unknown value {state} from backend"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -284,7 +289,7 @@ async fn main() -> Result<()> {
|
||||||
println!("GPU Power Profile: {profile} {name}");
|
println!("GPU Power Profile: {profile} {name}");
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
println!("Unknown GPU power profile or unable to get type from {profile}")
|
println!("Unknown GPU power profile or unable to get type from {profile}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -304,7 +309,7 @@ async fn main() -> Result<()> {
|
||||||
let proxy = GpuPerformanceLevel1Proxy::new(&conn).await?;
|
let proxy = GpuPerformanceLevel1Proxy::new(&conn).await?;
|
||||||
let level = proxy.gpu_performance_level().await?;
|
let level = proxy.gpu_performance_level().await?;
|
||||||
match GPUPerformanceLevel::try_from(level.as_str()) {
|
match GPUPerformanceLevel::try_from(level.as_str()) {
|
||||||
Ok(l) => println!("GPU performance level: {}", l),
|
Ok(l) => println!("GPU performance level: {l}"),
|
||||||
Err(_) => println!("Got unknown value {level} from backend"),
|
Err(_) => println!("Got unknown value {level} from backend"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ impl<C: DaemonContext> Daemon<C> {
|
||||||
let token = CancellationToken::new();
|
let token = CancellationToken::new();
|
||||||
|
|
||||||
let log_receiver = LogReceiver::new(connection.clone()).await?;
|
let log_receiver = LogReceiver::new(connection.clone()).await?;
|
||||||
let remote_logger = LogLayer::new(&log_receiver).await;
|
let remote_logger = LogLayer::new(&log_receiver);
|
||||||
let subscriber = subscriber
|
let subscriber = subscriber
|
||||||
.with(EnvFilter::from_default_env())
|
.with(EnvFilter::from_default_env())
|
||||||
.with(remote_logger);
|
.with(remote_logger);
|
||||||
|
@ -90,8 +90,8 @@ impl<C: DaemonContext> Daemon<C> {
|
||||||
let mut daemon = Daemon {
|
let mut daemon = Daemon {
|
||||||
services,
|
services,
|
||||||
token,
|
token,
|
||||||
channel,
|
|
||||||
connection,
|
connection,
|
||||||
|
channel,
|
||||||
};
|
};
|
||||||
daemon.add_service(log_receiver);
|
daemon.add_service(log_receiver);
|
||||||
|
|
||||||
|
@ -134,11 +134,11 @@ impl<C: DaemonContext> Daemon<C> {
|
||||||
},
|
},
|
||||||
_ = tokio::signal::ctrl_c() => break Ok(()),
|
_ = tokio::signal::ctrl_c() => break Ok(()),
|
||||||
e = sigterm.recv() => match e {
|
e = sigterm.recv() => match e {
|
||||||
Some(_) => Ok(()),
|
Some(()) => Ok(()),
|
||||||
None => Err(anyhow!("SIGTERM machine broke")),
|
None => Err(anyhow!("SIGTERM machine broke")),
|
||||||
},
|
},
|
||||||
e = sighup.recv() => match e {
|
e = sighup.recv() => match e {
|
||||||
Some(_) => {
|
Some(()) => {
|
||||||
match read_config(&context).await {
|
match read_config(&context).await {
|
||||||
Ok(config) =>
|
Ok(config) =>
|
||||||
context.reload(config, self).await,
|
context.reload(config, self).await,
|
||||||
|
|
|
@ -77,7 +77,7 @@ impl HidNode {
|
||||||
|
|
||||||
if !matches!(
|
if !matches!(
|
||||||
driver.file_name().and_then(|d| d.to_str()),
|
driver.file_name().and_then(|d| d.to_str()),
|
||||||
Some("sony") | Some("playstation")
|
Some("sony" | "playstation")
|
||||||
) {
|
) {
|
||||||
debug!("Not a PlayStation controller");
|
debug!("Not a PlayStation controller");
|
||||||
return false;
|
return false;
|
||||||
|
@ -101,9 +101,8 @@ impl HidNode {
|
||||||
let mut dir = read_dir(path("/proc")).await?;
|
let mut dir = read_dir(path("/proc")).await?;
|
||||||
while let Some(entry) = dir.next_entry().await? {
|
while let Some(entry) = dir.next_entry().await? {
|
||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
let proc = match path.file_name().map(|p| p.to_str()) {
|
let Some(Some(proc)) = path.file_name().map(|p| p.to_str()) else {
|
||||||
Some(Some(p)) => p,
|
continue;
|
||||||
_ => continue,
|
|
||||||
};
|
};
|
||||||
let _: u32 = match proc.parse() {
|
let _: u32 = match proc.parse() {
|
||||||
Ok(i) => i,
|
Ok(i) => i,
|
||||||
|
@ -147,7 +146,7 @@ impl HidNode {
|
||||||
|
|
||||||
async fn inhibit(&self) -> Result<()> {
|
async fn inhibit(&self) -> Result<()> {
|
||||||
let mut res = Ok(());
|
let mut res = Ok(());
|
||||||
for node in self.get_nodes().await?.into_iter() {
|
for node in self.get_nodes().await? {
|
||||||
if let Err(err) = write_synced(node, b"1\n").await {
|
if let Err(err) = write_synced(node, b"1\n").await {
|
||||||
error!("Encountered error inhibiting: {err}");
|
error!("Encountered error inhibiting: {err}");
|
||||||
res = Err(err);
|
res = Err(err);
|
||||||
|
@ -158,7 +157,7 @@ impl HidNode {
|
||||||
|
|
||||||
async fn uninhibit(&self) -> Result<()> {
|
async fn uninhibit(&self) -> Result<()> {
|
||||||
let mut res = Ok(());
|
let mut res = Ok(());
|
||||||
for node in self.get_nodes().await?.into_iter() {
|
for node in self.get_nodes().await? {
|
||||||
if let Err(err) = write_synced(node, b"0\n").await {
|
if let Err(err) = write_synced(node, b"0\n").await {
|
||||||
error!("Encountered error inhibiting: {err}");
|
error!("Encountered error inhibiting: {err}");
|
||||||
res = Err(err);
|
res = Err(err);
|
||||||
|
@ -204,14 +203,13 @@ impl Inhibitor {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
let id = match path
|
let Some(id) = path
|
||||||
.file_name()
|
.file_name()
|
||||||
.and_then(|f| f.to_str())
|
.and_then(|f| f.to_str())
|
||||||
.and_then(|s| s.strip_prefix("hidraw"))
|
.and_then(|s| s.strip_prefix("hidraw"))
|
||||||
.and_then(|s| s.parse().ok())
|
.and_then(|s| s.parse().ok())
|
||||||
{
|
else {
|
||||||
Some(id) => id,
|
return Ok(false);
|
||||||
None => return Ok(false),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let node = HidNode::new(id);
|
let node = HidNode::new(id);
|
||||||
|
@ -240,12 +238,11 @@ impl Inhibitor {
|
||||||
const QSEC: Duration = Duration::from_millis(250);
|
const QSEC: Duration = Duration::from_millis(250);
|
||||||
debug!("Got event: {:08x}", event.mask);
|
debug!("Got event: {:08x}", event.mask);
|
||||||
if event.wd == self.dev_watch {
|
if event.wd == self.dev_watch {
|
||||||
let path = match event.name {
|
let path = if let Some(fname) = event.name {
|
||||||
Some(fname) => PathBuf::from(fname),
|
PathBuf::from(fname)
|
||||||
None => {
|
} else {
|
||||||
error!("Got an event without an associated filename!");
|
error!("Got an event without an associated filename!");
|
||||||
return Err(anyhow!("Got an event without an associated filename"));
|
return Err(anyhow!("Got an event without an associated filename"));
|
||||||
}
|
|
||||||
};
|
};
|
||||||
debug!("New device {} found", path.display());
|
debug!("New device {} found", path.display());
|
||||||
let path = crate::path("/dev").join(path);
|
let path = crate::path("/dev").join(path);
|
||||||
|
@ -315,7 +312,7 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} => res,
|
} => res,
|
||||||
_ = sleep(Duration::from_millis(500)) => false,
|
() = sleep(Duration::from_millis(500)) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,12 @@
|
||||||
|
|
||||||
use zbus::fdo;
|
use zbus::fdo;
|
||||||
|
|
||||||
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
pub fn to_zbus_fdo_error<S: ToString>(error: S) -> fdo::Error {
|
pub fn to_zbus_fdo_error<S: ToString>(error: S) -> fdo::Error {
|
||||||
fdo::Error::Failed(error.to_string())
|
fdo::Error::Failed(error.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
pub fn to_zbus_error<S: ToString>(error: S) -> zbus::Error {
|
pub fn to_zbus_error<S: ToString>(error: S) -> zbus::Error {
|
||||||
zbus::Error::Failure(error.to_string())
|
zbus::Error::Failure(error.to_string())
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,9 +159,10 @@ impl FanControl {
|
||||||
let jupiter_fan_control =
|
let jupiter_fan_control =
|
||||||
SystemdUnit::new(self.connection.clone(), 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(if active {
|
||||||
true => FanControlState::Os,
|
FanControlState::Os
|
||||||
false => FanControlState::Bios,
|
} else {
|
||||||
|
FanControlState::Bios
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Some(ServiceConfig::Script {
|
Some(ServiceConfig::Script {
|
||||||
|
|
30
src/job.rs
30
src/job.rs
|
@ -143,7 +143,7 @@ impl JobManager {
|
||||||
let job = MirroredJob { job: proxy };
|
let job = MirroredJob { job: proxy };
|
||||||
|
|
||||||
let object_path = self.add_job(job).await?;
|
let object_path = self.add_job(job).await?;
|
||||||
self.mirrored_jobs.insert(name, object_path.to_owned());
|
self.mirrored_jobs.insert(name, object_path.clone());
|
||||||
Ok(object_path)
|
Ok(object_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,9 +186,8 @@ impl Job {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_signal(&self, signal: nix::sys::signal::Signal) -> Result<()> {
|
fn send_signal(&self, signal: nix::sys::signal::Signal) -> Result<()> {
|
||||||
let pid = match self.process.id() {
|
let Some(pid) = self.process.id() else {
|
||||||
Some(id) => id,
|
bail!("Unable to get pid from command, it likely finished running");
|
||||||
None => bail!("Unable to get pid from command, it likely finished running"),
|
|
||||||
};
|
};
|
||||||
let pid: pid_t = match pid.try_into() {
|
let pid: pid_t = match pid.try_into() {
|
||||||
Ok(pid) => pid,
|
Ok(pid) => pid,
|
||||||
|
@ -257,9 +256,10 @@ impl Job {
|
||||||
|
|
||||||
pub async fn cancel(&mut self, force: bool) -> fdo::Result<()> {
|
pub async fn cancel(&mut self, force: bool) -> fdo::Result<()> {
|
||||||
if self.try_wait().map_err(to_zbus_fdo_error)?.is_none() {
|
if self.try_wait().map_err(to_zbus_fdo_error)?.is_none() {
|
||||||
self.send_signal(match force {
|
self.send_signal(if force {
|
||||||
true => Signal::SIGKILL,
|
Signal::SIGKILL
|
||||||
false => Signal::SIGTERM,
|
} else {
|
||||||
|
Signal::SIGTERM
|
||||||
})
|
})
|
||||||
.map_err(to_zbus_fdo_error)?;
|
.map_err(to_zbus_fdo_error)?;
|
||||||
if self.paused {
|
if self.paused {
|
||||||
|
@ -274,14 +274,12 @@ impl Job {
|
||||||
self.resume().await?;
|
self.resume().await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let code = match self.wait_internal().await.map_err(to_zbus_fdo_error) {
|
if let Ok(code) = self.wait_internal().await.map_err(to_zbus_fdo_error) {
|
||||||
Ok(v) => v,
|
self.exit_code = Some(code);
|
||||||
Err(_) => {
|
Ok(code)
|
||||||
return Err(fdo::Error::Failed("Unable to get exit code".to_string()));
|
} else {
|
||||||
}
|
Err(fdo::Error::Failed("Unable to get exit code".to_string()))
|
||||||
};
|
}
|
||||||
self.exit_code = Some(code);
|
|
||||||
Ok(code)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +318,7 @@ impl JobManagerService {
|
||||||
async fn handle_command(&mut self, command: JobManagerCommand) -> Result<()> {
|
async fn handle_command(&mut self, command: JobManagerCommand) -> Result<()> {
|
||||||
match command {
|
match command {
|
||||||
JobManagerCommand::MirrorConnection(connection) => {
|
JobManagerCommand::MirrorConnection(connection) => {
|
||||||
self.job_manager.mirror_connection(&connection).await?
|
self.job_manager.mirror_connection(&connection).await?;
|
||||||
}
|
}
|
||||||
JobManagerCommand::MirrorJob {
|
JobManagerCommand::MirrorJob {
|
||||||
connection,
|
connection,
|
||||||
|
|
39
src/lib.rs
39
src/lib.rs
|
@ -5,7 +5,7 @@
|
||||||
* SPDX-License-Identifier: MIT
|
* SPDX-License-Identifier: MIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{bail, Result};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use config::builder::AsyncState;
|
use config::builder::AsyncState;
|
||||||
use config::{AsyncSource, ConfigBuilder, ConfigError, FileFormat, Format, Map, Value};
|
use config::{AsyncSource, ConfigBuilder, ConfigError, FileFormat, Format, Map, Value};
|
||||||
|
@ -58,7 +58,7 @@ where
|
||||||
info!("Starting {}", Self::NAME);
|
info!("Starting {}", Self::NAME);
|
||||||
let res = tokio::select! {
|
let res = tokio::select! {
|
||||||
r = self.run() => r,
|
r = self.run() => r,
|
||||||
_ = token.cancelled() => Ok(()),
|
() = token.cancelled() => Ok(()),
|
||||||
};
|
};
|
||||||
if res.is_err() {
|
if res.is_err() {
|
||||||
warn!(
|
warn!(
|
||||||
|
@ -129,36 +129,35 @@ pub(crate) async fn write_synced<P: AsRef<Path>>(path: P, bytes: &[u8]) -> Resul
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn read_comm(pid: u32) -> Result<String> {
|
pub(crate) fn read_comm(pid: u32) -> Result<String> {
|
||||||
let comm = std::fs::read_to_string(path(format!("/proc/{}/comm", pid)))?;
|
let comm = std::fs::read_to_string(path(format!("/proc/{pid}/comm")))?;
|
||||||
Ok(comm.trim_end().to_string())
|
Ok(comm.trim_end().to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_appid(pid: u32) -> Result<Option<u64>> {
|
pub(crate) fn get_appid(pid: u32) -> Result<Option<u64>> {
|
||||||
let environ = std::fs::read_to_string(path(format!("/proc/{}/environ", pid)))?;
|
let environ = std::fs::read_to_string(path(format!("/proc/{pid}/environ")))?;
|
||||||
for env_var in environ.split('\0') {
|
for env_var in environ.split('\0') {
|
||||||
let (key, value) = match env_var.split_once('=') {
|
let Some((key, value)) = env_var.split_once('=') else {
|
||||||
Some((k, v)) => (k, v),
|
continue;
|
||||||
None => continue,
|
|
||||||
};
|
};
|
||||||
if key != "SteamGameId" {
|
if key != "SteamGameId" {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
match value.parse() {
|
if let Ok(appid) = value.parse() {
|
||||||
Ok(appid) => return Ok(Some(appid)),
|
return Ok(Some(appid));
|
||||||
Err(_) => break,
|
}
|
||||||
};
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let stat = std::fs::read_to_string(path(format!("/proc/{}/stat", pid)))?;
|
let stat = std::fs::read_to_string(path(format!("/proc/{pid}/stat")))?;
|
||||||
let stat = match stat.rsplit_once(") ") {
|
let ppid: u32 = if let Some((_, stat)) = stat.rsplit_once(") ") {
|
||||||
Some((_, v)) => v,
|
if let Some(ppid) = stat.split(' ').nth(1) {
|
||||||
None => return Ok(None),
|
ppid.parse()?
|
||||||
|
} else {
|
||||||
|
bail!("stat data invalid");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Ok(None);
|
||||||
};
|
};
|
||||||
let ppid = match stat.split(' ').nth(1) {
|
|
||||||
Some(ppid) => ppid,
|
|
||||||
None => return Err(anyhow!("stat data invalid")),
|
|
||||||
};
|
|
||||||
let ppid: u32 = ppid.parse()?;
|
|
||||||
if ppid > 1 {
|
if ppid > 1 {
|
||||||
get_appid(ppid)
|
get_appid(ppid)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -91,7 +91,7 @@ impl SteamOSManager {
|
||||||
config = factory_reset ("PrepareFactoryReset") => {
|
config = factory_reset ("PrepareFactoryReset") => {
|
||||||
let res = run_script(&config.script, &config.script_args).await;
|
let res = run_script(&config.script, &config.script_args).await;
|
||||||
Ok(match res {
|
Ok(match res {
|
||||||
Ok(_) => PrepareFactoryReset::RebootRequired as u32,
|
Ok(()) => PrepareFactoryReset::RebootRequired as u32,
|
||||||
Err(_) => PrepareFactoryReset::Unknown as u32,
|
Err(_) => PrepareFactoryReset::Unknown as u32,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -302,7 +302,10 @@ impl SteamOSManager {
|
||||||
Ok(mode) => mode,
|
Ok(mode) => mode,
|
||||||
Err(e) => return Err(fdo::Error::InvalidArgs(e.to_string())),
|
Err(e) => return Err(fdo::Error::InvalidArgs(e.to_string())),
|
||||||
};
|
};
|
||||||
let buffer_size = match options.get("buffer_size").map(|v| v.downcast_ref::<u32>()) {
|
let buffer_size = match options
|
||||||
|
.get("buffer_size")
|
||||||
|
.map(zbus::zvariant::Value::downcast_ref)
|
||||||
|
{
|
||||||
Some(Ok(v)) => v,
|
Some(Ok(v)) => v,
|
||||||
None => 20000,
|
None => 20000,
|
||||||
Some(Err(e)) => return Err(fdo::Error::InvalidArgs(e.to_string())),
|
Some(Err(e)) => return Err(fdo::Error::InvalidArgs(e.to_string())),
|
||||||
|
|
|
@ -506,6 +506,7 @@ impl WifiPowerManagement1 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_lines)]
|
||||||
pub(crate) async fn create_interfaces(
|
pub(crate) async fn create_interfaces(
|
||||||
session: Connection,
|
session: Connection,
|
||||||
system: Connection,
|
system: Connection,
|
||||||
|
@ -760,7 +761,7 @@ mod test {
|
||||||
async fn test_interface_missing<I: Interface>(connection: &Connection) -> bool {
|
async fn test_interface_missing<I: Interface>(connection: &Connection) -> bool {
|
||||||
let remote =
|
let remote =
|
||||||
testing::InterfaceIntrospection::from_remote::<I, _>(connection, MANAGER_PATH).await;
|
testing::InterfaceIntrospection::from_remote::<I, _>(connection, MANAGER_PATH).await;
|
||||||
return remote.is_err();
|
remote.is_err()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|
64
src/power.rs
64
src/power.rs
|
@ -123,30 +123,26 @@ async fn write_cpu_governor_sysfs_contents(contents: String) -> Result<()> {
|
||||||
let mut dir = fs::read_dir(path(CPU_PREFIX)).await?;
|
let mut dir = fs::read_dir(path(CPU_PREFIX)).await?;
|
||||||
let mut wrote_stuff = false;
|
let mut wrote_stuff = false;
|
||||||
loop {
|
loop {
|
||||||
let base = match dir.next_entry().await? {
|
let Some(entry) = dir.next_entry().await? else {
|
||||||
Some(entry) => {
|
ensure!(
|
||||||
let file_name = entry
|
wrote_stuff,
|
||||||
.file_name()
|
"No data written, unable to find any policyX sysfs paths"
|
||||||
.into_string()
|
);
|
||||||
.map_err(|_| anyhow!("Unable to convert path to string"))?;
|
return Ok(());
|
||||||
if !file_name.starts_with(CPU_POLICY_NAME) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
entry.path()
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
ensure!(
|
|
||||||
wrote_stuff,
|
|
||||||
"No data written, unable to find any policyX sysfs paths"
|
|
||||||
);
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
let file_name = entry
|
||||||
|
.file_name()
|
||||||
|
.into_string()
|
||||||
|
.map_err(|_| anyhow!("Unable to convert path to string"))?;
|
||||||
|
if !file_name.starts_with(CPU_POLICY_NAME) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let base = entry.path();
|
||||||
// Write contents to each one
|
// Write contents to each one
|
||||||
wrote_stuff = true;
|
wrote_stuff = true;
|
||||||
write_synced(base.join(CPU_SCALING_GOVERNOR_SUFFIX), contents.as_bytes())
|
write_synced(base.join(CPU_SCALING_GOVERNOR_SUFFIX), contents.as_bytes())
|
||||||
.await
|
.await
|
||||||
.inspect_err(|message| error!("Error writing to sysfs file: {message}"))?
|
.inspect_err(|message| error!("Error writing to sysfs file: {message}"))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,10 +154,8 @@ pub(crate) async fn get_gpu_power_profile() -> Result<GPUPowerProfile> {
|
||||||
// firmware support setting the value to no-op values.
|
// firmware support setting the value to no-op values.
|
||||||
let lines = contents.lines();
|
let lines = contents.lines();
|
||||||
for line in lines {
|
for line in lines {
|
||||||
let caps = GPU_POWER_PROFILE_REGEX.captures(line);
|
let Some(caps) = GPU_POWER_PROFILE_REGEX.captures(line) else {
|
||||||
let caps = match caps {
|
continue;
|
||||||
Some(caps) => caps,
|
|
||||||
None => continue,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let name = &caps["name"].to_lowercase();
|
let name = &caps["name"].to_lowercase();
|
||||||
|
@ -184,10 +178,8 @@ pub(crate) async fn get_available_gpu_power_profiles() -> Result<Vec<(u32, Strin
|
||||||
let mut map = Vec::new();
|
let mut map = Vec::new();
|
||||||
let lines = contents.lines();
|
let lines = contents.lines();
|
||||||
for line in lines {
|
for line in lines {
|
||||||
let caps = GPU_POWER_PROFILE_REGEX.captures(line);
|
let Some(caps) = GPU_POWER_PROFILE_REGEX.captures(line) else {
|
||||||
let caps = match caps {
|
continue;
|
||||||
Some(caps) => caps,
|
|
||||||
None => continue,
|
|
||||||
};
|
};
|
||||||
let value: u32 = caps["value"]
|
let value: u32 = caps["value"]
|
||||||
.parse()
|
.parse()
|
||||||
|
@ -217,9 +209,7 @@ pub(crate) async fn set_gpu_power_profile(value: GPUPowerProfile) -> Result<()>
|
||||||
|
|
||||||
pub(crate) async fn get_available_gpu_performance_levels() -> Result<Vec<GPUPerformanceLevel>> {
|
pub(crate) async fn get_available_gpu_performance_levels() -> Result<Vec<GPUPerformanceLevel>> {
|
||||||
let base = find_hwmon().await?;
|
let base = find_hwmon().await?;
|
||||||
if !try_exists(base.join(GPU_PERFORMANCE_LEVEL_SUFFIX)).await? {
|
if try_exists(base.join(GPU_PERFORMANCE_LEVEL_SUFFIX)).await? {
|
||||||
Ok(Vec::new())
|
|
||||||
} else {
|
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
GPUPerformanceLevel::Auto,
|
GPUPerformanceLevel::Auto,
|
||||||
GPUPerformanceLevel::Low,
|
GPUPerformanceLevel::Low,
|
||||||
|
@ -227,6 +217,8 @@ pub(crate) async fn get_available_gpu_performance_levels() -> Result<Vec<GPUPerf
|
||||||
GPUPerformanceLevel::Manual,
|
GPUPerformanceLevel::Manual,
|
||||||
GPUPerformanceLevel::ProfilePeak,
|
GPUPerformanceLevel::ProfilePeak,
|
||||||
])
|
])
|
||||||
|
} else {
|
||||||
|
Ok(Vec::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,14 +269,12 @@ pub(crate) async fn set_cpu_scaling_governor(governor: CPUScalingGovernor) -> Re
|
||||||
pub(crate) async fn get_gpu_clocks_range() -> Result<(u32, u32)> {
|
pub(crate) async fn get_gpu_clocks_range() -> Result<(u32, u32)> {
|
||||||
let contents = read_gpu_sysfs_contents(GPU_CLOCK_LEVELS_SUFFIX).await?;
|
let contents = read_gpu_sysfs_contents(GPU_CLOCK_LEVELS_SUFFIX).await?;
|
||||||
let lines = contents.lines();
|
let lines = contents.lines();
|
||||||
let mut min = 1000000;
|
let mut min = 1_000_000;
|
||||||
let mut max = 0;
|
let mut max = 0;
|
||||||
|
|
||||||
for line in lines {
|
for line in lines {
|
||||||
let caps = GPU_CLOCK_LEVELS_REGEX.captures(line);
|
let Some(caps) = GPU_CLOCK_LEVELS_REGEX.captures(line) else {
|
||||||
let caps = match caps {
|
continue;
|
||||||
Some(caps) => caps,
|
|
||||||
None => continue,
|
|
||||||
};
|
};
|
||||||
let value: u32 = caps["value"]
|
let value: u32 = caps["value"]
|
||||||
.parse()
|
.parse()
|
||||||
|
@ -381,7 +371,7 @@ pub(crate) async fn get_tdp_limit() -> Result<u32> {
|
||||||
let base = find_hwmon().await?;
|
let base = find_hwmon().await?;
|
||||||
let power1cap = fs::read_to_string(base.join(TDP_LIMIT1)).await?;
|
let power1cap = fs::read_to_string(base.join(TDP_LIMIT1)).await?;
|
||||||
let power1cap: u32 = power1cap.trim_end().parse()?;
|
let power1cap: u32 = power1cap.trim_end().parse()?;
|
||||||
Ok(power1cap / 1000000)
|
Ok(power1cap / 1_000_000)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) async fn set_tdp_limit(limit: u32) -> Result<()> {
|
pub(crate) async fn set_tdp_limit(limit: u32) -> Result<()> {
|
||||||
|
@ -394,7 +384,7 @@ pub(crate) async fn set_tdp_limit(limit: u32) -> Result<()> {
|
||||||
write_synced(base.join(TDP_LIMIT1), data.as_bytes())
|
write_synced(base.join(TDP_LIMIT1), data.as_bytes())
|
||||||
.await
|
.await
|
||||||
.inspect_err(|message| {
|
.inspect_err(|message| {
|
||||||
error!("Error opening sysfs power1_cap file for writing TDP limits {message}")
|
error!("Error opening sysfs power1_cap file for writing TDP limits {message}");
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if let Ok(mut power2file) = File::create(base.join(TDP_LIMIT2)).await {
|
if let Ok(mut power2file) = File::create(base.join(TDP_LIMIT2)).await {
|
||||||
|
|
|
@ -33,7 +33,7 @@ pub async fn script_exit_code(
|
||||||
args: &[impl AsRef<OsStr>],
|
args: &[impl AsRef<OsStr>],
|
||||||
) -> Result<i32> {
|
) -> Result<i32> {
|
||||||
let test = crate::testing::current();
|
let test = crate::testing::current();
|
||||||
let args: Vec<&OsStr> = args.iter().map(|arg| arg.as_ref()).collect();
|
let args: Vec<&OsStr> = args.iter().map(std::convert::AsRef::as_ref).collect();
|
||||||
let cb = test.process_cb.get();
|
let cb = test.process_cb.get();
|
||||||
cb(executable.as_ref(), args.as_ref()).map(|(res, _)| res)
|
cb(executable.as_ref(), args.as_ref()).map(|(res, _)| res)
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ pub async fn script_output(
|
||||||
args: &[impl AsRef<OsStr>],
|
args: &[impl AsRef<OsStr>],
|
||||||
) -> Result<String> {
|
) -> Result<String> {
|
||||||
let test = crate::testing::current();
|
let test = crate::testing::current();
|
||||||
let args: Vec<&OsStr> = args.iter().map(|arg| arg.as_ref()).collect();
|
let args: Vec<&OsStr> = args.iter().map(std::convert::AsRef::as_ref).collect();
|
||||||
let cb = test.process_cb.get();
|
let cb = test.process_cb.get();
|
||||||
cb(executable.as_ref(), args.as_ref()).map(|(_, res)| res)
|
cb(executable.as_ref(), args.as_ref()).map(|(_, res)| res)
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ async fn setup_traces(base: &Path) -> Result<()> {
|
||||||
if !string.starts_with("flags") {
|
if !string.starts_with("flags") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let Some((_, rest)) = string.split_once(":") {
|
if let Some((_, rest)) = string.split_once(':') {
|
||||||
let mut flags = rest.split_whitespace();
|
let mut flags = rest.split_whitespace();
|
||||||
if flags.any(|flag| flag == "split_lock_detect") {
|
if flags.any(|flag| flag == "split_lock_detect") {
|
||||||
fs::write(base.join("set_ftrace_filter"), "split_lock_warn").await?;
|
fs::write(base.join("set_ftrace_filter"), "split_lock_warn").await?;
|
||||||
|
@ -196,7 +196,7 @@ mod test {
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*map.get("appid").expect("appid"),
|
*map.get("appid").expect("appid"),
|
||||||
zvariant::Value::new(5678 as u64)
|
zvariant::Value::new(5678_u64)
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
|
@ -212,7 +212,7 @@ mod test {
|
||||||
assert!(map.get("comm").is_none());
|
assert!(map.get("comm").is_none());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*map.get("appid").expect("appid"),
|
*map.get("appid").expect("appid"),
|
||||||
zvariant::Value::new(5678 as u64)
|
zvariant::Value::new(5678_u64)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,7 +349,7 @@ mod test {
|
||||||
assert_eq!(data.len(), 2);
|
assert_eq!(data.len(), 2);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
data.get("appid").map(|v| v.downcast_ref()),
|
data.get("appid").map(|v| v.downcast_ref()),
|
||||||
Some(Ok(5678 as u64))
|
Some(Ok(5678_u64))
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
data.get("comm").map(|v| v.downcast_ref()),
|
data.get("comm").map(|v| v.downcast_ref()),
|
||||||
|
|
|
@ -90,7 +90,7 @@ impl Service for LogReceiver {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LogLayer {
|
impl LogLayer {
|
||||||
pub async fn new(receiver: &LogReceiver) -> LogLayer {
|
pub fn new(receiver: &LogReceiver) -> LogLayer {
|
||||||
LogLayer {
|
LogLayer {
|
||||||
queue: receiver.sender.clone(),
|
queue: receiver.sender.clone(),
|
||||||
}
|
}
|
||||||
|
@ -111,8 +111,7 @@ impl<S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>> Layer
|
||||||
prefix + "." + suffix
|
prefix + "." + suffix
|
||||||
});
|
});
|
||||||
let level = match *event.metadata().level() {
|
let level = match *event.metadata().level() {
|
||||||
Level::TRACE => 10,
|
Level::TRACE | Level::DEBUG => 10,
|
||||||
Level::DEBUG => 10,
|
|
||||||
Level::INFO => 20,
|
Level::INFO => 20,
|
||||||
Level::WARN => 30,
|
Level::WARN => 30,
|
||||||
Level::ERROR => 40,
|
Level::ERROR => 40,
|
||||||
|
|
|
@ -401,13 +401,13 @@ pub mod test {
|
||||||
let unit = SystemdUnit::new(connection.clone(), "test.service")
|
let unit = SystemdUnit::new(connection.clone(), "test.service")
|
||||||
.await
|
.await
|
||||||
.expect("unit");
|
.expect("unit");
|
||||||
assert_eq!(unit.enable().await.unwrap(), true);
|
assert!(unit.enable().await.unwrap());
|
||||||
assert_eq!(unit.enable().await.unwrap(), false);
|
assert!(!unit.enable().await.unwrap());
|
||||||
assert_eq!(unit.disable().await.unwrap(), true);
|
assert!(unit.disable().await.unwrap());
|
||||||
assert_eq!(unit.disable().await.unwrap(), false);
|
assert!(!unit.disable().await.unwrap());
|
||||||
assert_eq!(unit.mask().await.unwrap(), true);
|
assert!(unit.mask().await.unwrap());
|
||||||
assert_eq!(unit.mask().await.unwrap(), false);
|
assert!(!unit.mask().await.unwrap());
|
||||||
assert_eq!(unit.unmask().await.unwrap(), true);
|
assert!(unit.unmask().await.unwrap());
|
||||||
assert_eq!(unit.unmask().await.unwrap(), false);
|
assert!(!unit.unmask().await.unwrap());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ use zbus_xml::{Method, Node, Property};
|
||||||
use crate::platform::PlatformConfig;
|
use crate::platform::PlatformConfig;
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
static TEST: RefCell<Option<Rc<Test>>> = RefCell::new(None);
|
static TEST: RefCell<Option<Rc<Test>>> = const { RefCell::new(None) };
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
@ -233,7 +233,7 @@ impl<'a> InterfaceIntrospection<'a> {
|
||||||
|
|
||||||
fn collect_methods(&self) -> HashMap<String, &Method<'_>> {
|
fn collect_methods(&self) -> HashMap<String, &Method<'_>> {
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
for method in self.interface.methods().iter() {
|
for method in self.interface.methods() {
|
||||||
map.insert(method.name().to_string(), method);
|
map.insert(method.name().to_string(), method);
|
||||||
}
|
}
|
||||||
map
|
map
|
||||||
|
@ -241,7 +241,7 @@ impl<'a> InterfaceIntrospection<'a> {
|
||||||
|
|
||||||
fn collect_properties(&self) -> HashMap<String, &Property<'_>> {
|
fn collect_properties(&self) -> HashMap<String, &Property<'_>> {
|
||||||
let mut map = HashMap::new();
|
let mut map = HashMap::new();
|
||||||
for prop in self.interface.properties().iter() {
|
for prop in self.interface.properties() {
|
||||||
map.insert(prop.name().to_string(), prop);
|
map.insert(prop.name().to_string(), prop);
|
||||||
}
|
}
|
||||||
map
|
map
|
||||||
|
|
10
src/udev.rs
10
src/udev.rs
|
@ -51,7 +51,7 @@ impl Service for UdevMonitor {
|
||||||
.shutdown_receiver
|
.shutdown_receiver
|
||||||
.take()
|
.take()
|
||||||
.ok_or(anyhow!("UdevMonitor cannot be run twice"))?;
|
.ok_or(anyhow!("UdevMonitor cannot be run twice"))?;
|
||||||
let mut handle = spawn(move || run_udev(ev_sender, shutdown_receiver));
|
let mut handle = spawn(move || run_udev(&ev_sender, &shutdown_receiver));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let handle = &mut handle;
|
let handle = &mut handle;
|
||||||
|
@ -71,7 +71,7 @@ impl Service for UdevMonitor {
|
||||||
port.as_str(),
|
port.as_str(),
|
||||||
count,
|
count,
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ impl UdevDbusObject {
|
||||||
) -> zbus::Result<()>;
|
) -> zbus::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_udev(tx: UnboundedSender<UdevEvent>, rx: OwnedFd) -> Result<()> {
|
fn run_udev(tx: &UnboundedSender<UdevEvent>, rx: &OwnedFd) -> Result<()> {
|
||||||
let usb_monitor = MonitorBuilder::new()?
|
let usb_monitor = MonitorBuilder::new()?
|
||||||
.match_subsystem_devtype("usb", "usb_interface")?
|
.match_subsystem_devtype("usb", "usb_interface")?
|
||||||
.listen()?;
|
.listen()?;
|
||||||
|
@ -137,7 +137,7 @@ fn run_udev(tx: UnboundedSender<UdevEvent>, rx: OwnedFd) -> Result<()> {
|
||||||
let ev = iter
|
let ev = iter
|
||||||
.next()
|
.next()
|
||||||
.ok_or(anyhow!("Poller said event was present, but it was not"))?;
|
.ok_or(anyhow!("Poller said event was present, but it was not"))?;
|
||||||
process_usb_event(ev, &tx)?;
|
process_usb_event(&ev, tx)?;
|
||||||
}
|
}
|
||||||
Some(false) => (),
|
Some(false) => (),
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ fn run_udev(tx: UnboundedSender<UdevEvent>, rx: OwnedFd) -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_usb_event(ev: Event, tx: &UnboundedSender<UdevEvent>) -> Result<()> {
|
fn process_usb_event(ev: &Event, tx: &UnboundedSender<UdevEvent>) -> Result<()> {
|
||||||
debug!("Got USB event {ev:?}");
|
debug!("Got USB event {ev:?}");
|
||||||
if ev.event_type() != EventType::Change {
|
if ev.event_type() != EventType::Change {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue