Skip to content

Commit

Permalink
Account for multipart driver versions when checking compatibility
Browse files Browse the repository at this point in the history
This fixes a bug where `nvfancontrol` expects the driver version to
always be in the format "XXX.YY". This is true for stable releases but
beta and experimental drivers usually have a third part "XXX.YY.ZZ" which
would lead to a crash when trying to parse it into a float. This is now
addressed by splitting the driver version on the dots "." and keeping only
the first two parts (or "00" if only one part is found).
  • Loading branch information
foucault committed Dec 23, 2019
1 parent 043c9ac commit 0f642a6
Showing 1 changed file with 32 additions and 10 deletions.
42 changes: 32 additions & 10 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,21 +95,15 @@ impl NVFanManager {

let ctrl = NvidiaControl::new(limits)?;
let gpu_count = ctrl.gpu_count()?;
let version: f32 = match ctrl.get_version() {
match ctrl.get_version() {
Ok(v) => {
v.parse::<f32>().unwrap()
validate_driver_version(v)?;
}
Err(e) => {
return Err(format!("Could not get driver version: {}", e))
}
};

if version < MIN_VERSION {
let err = format!("Unsupported driver version; need >= {:.2}",
MIN_VERSION);
return Err(err);
}

if gpu > gpu_count-1 {
return Err(format!("GPU id {} is not valid; min: 0 max: {}", gpu, gpu_count-1));
}
Expand Down Expand Up @@ -486,6 +480,34 @@ fn validate_gpu_id(gpu: u32) -> Result<(), String> {
}
}

fn validate_driver_version(version: String) -> Result<(), String> {
let parts: Vec<&str> = version.split(".").collect();

let major = parts[0];
let minor: &str;
if parts.len() < 2 {
minor = "00";
} else {
minor = parts[1];
}

let version_str = format!("{}.{}", major, minor);
let version_num = version_str.parse::<f32>();

if version_num.is_err() {
return Err("Could not parse driver version".to_string());
}

if version_num.unwrap() < MIN_VERSION {
let err = format!("Unsupported driver version; need >= {:.2}",
MIN_VERSION);
return Err(err);
}

Ok(())

}

trait ProcessOrDefault<T> {
fn opt_process_or_default<F>(&self, nm: &str, on_arg: F, default: T) -> T
where F: Fn(&str) -> T;
Expand Down Expand Up @@ -650,8 +672,8 @@ pub fn main() {
}
};

info!("NVIDIA driver version: {:.2}",
mgr.ctrl.get_version().unwrap().parse::<f32>().unwrap());
info!("NVIDIA driver version: {}",
mgr.ctrl.get_version().unwrap());
let gpu_count = mgr.ctrl.gpu_count().unwrap();
for i in 0u32..gpu_count {
info!("NVIDIA graphics adapter #{}: {}", i,
Expand Down

0 comments on commit 0f642a6

Please sign in to comment.