feat(src/commands): enhance error handling, logging, and robustness in GPU command implementations

- **New Features**: Added detailed error logging for signal handling, directory creation, cache file operations, and service management; improved cleanup with explicit error propagation.
- **Enhancements**: Refactored Drop implementations to handle failures gracefully; upgraded status handling for systemctl commands with precise exit code reporting; strengthened directory and file removal with debug logging.
- **Bug Fixes**: Fixed missing error propagation in Ctrl+C handler; corrected service enable/disable status reporting; ensured proper removal of cache files and directories with appropriate logging of failures.
This commit is contained in:
sankalp committed 2026-05-25 14:49:48 +05:45
1 parent 02f8ff4c33
commit 191afd2f12
2 files changed
+81 -27

No files matched your search

+50 -17
View File
@@ -20,9 +20,11 @@ use zbus::proxy;
static INTERRUPTED: AtomicBool = AtomicBool::new(false);
fn setup_signal_handler() {
let _ = ctrlc::set_handler(|| {
if let Err(e) = ctrlc::set_handler(|| {
INTERRUPTED.store(true, Ordering::SeqCst);
});
}) {
log::debug!("Could not set Ctrl+C handler (may already be set): {}", e);
}
}
struct DmGuard {
@@ -33,7 +35,9 @@ impl Drop for DmGuard {
fn drop(&mut self) {
if let Some(ref name) = self.name {
info!("Restarting display manager: {}", name);
let _ = manage_service(name, "start");
if let Err(e) = manage_service(name, "start") {
error!("Failed to restart display manager '{}': {}", name, e);
}
}
}
}
@@ -55,7 +59,9 @@ impl LockGuard {
impl Drop for LockGuard {
fn drop(&mut self) {
let _ = fs::remove_file(LOCK_PATH);
if let Err(e) = fs::remove_file(LOCK_PATH) {
log::debug!("Failed to remove lock file: {}", e);
}
info!("Released lock");
}
}
@@ -455,8 +461,10 @@ fn create_cache_file() {
let bus_id = get_nvidia_gpu_pci_bus();
let cache = create_cache_obj(bus_id);
if let Some(parent) = Path::new(CACHE_FILE_PATH).parent() {
let _ = fs::create_dir_all(parent);
if let Some(parent) = Path::new(CACHE_FILE_PATH).parent()
&& let Err(e) = fs::create_dir_all(parent)
{
log::debug!("Failed to create cache directory: {}", e);
}
if let Ok(json) = serde_json::to_string_pretty(&cache) {
@@ -465,7 +473,10 @@ fn create_cache_file() {
if fs::rename(&tmp_path, CACHE_FILE_PATH).is_ok() {
log::debug!("Created/Updated cache file {}", CACHE_FILE_PATH);
} else {
let _ = fs::remove_file(&tmp_path);
if let Err(e) = fs::remove_file(&tmp_path) {
log::debug!("Failed to remove stale temp cache file: {}", e);
}
log::debug!("Failed to rename temp cache file");
}
}
}
@@ -552,7 +563,9 @@ fn switch_integrated(no_reboot: bool) {
// Try to unload modules
let modules = ["nvidia_uvm", "nvidia_modeset", "nvidia_drm", "nvidia"];
for module in modules {
let _ = Command::new("modprobe").args(["-r", module]).status();
if let Err(e) = Command::new("modprobe").args(["-r", module]).status() {
log::debug!("Failed to run modprobe -r {}: {}", module, e);
}
}
if let Some(pci_addr) = get_nvidia_gpu_pci_addr() {
@@ -578,7 +591,11 @@ fn switch_integrated(no_reboot: bool) {
}
match dis_cmd.status() {
Ok(s) if s.success() => println!("Successfully disabled nvidia-persistenced.service"),
_ => error!("An error ocurred while disabling service"),
Ok(s) => error!(
"nvidia-persistenced.service disable failed with exit code: {}",
s
),
Err(e) => error!("Failed to run systemctl: {}", e),
}
if no_reboot {
@@ -643,7 +660,11 @@ fn switch_hybrid(rtd3: Option<u8>, use_nvidia_current: bool, no_reboot: bool) {
}
match enable_cmd.status() {
Ok(s) if s.success() => println!("Successfully enabled nvidia-persistenced.service"),
_ => error!("An error ocurred while enabling service"),
Ok(s) => error!(
"nvidia-persistenced.service enable failed with exit code: {}",
s
),
Err(e) => error!("Failed to run systemctl: {}", e),
}
if let Some(val) = rtd3 {
@@ -815,7 +836,11 @@ fn switch_nvidia(
}
match enable_cmd.status() {
Ok(s) if s.success() => println!("Successfully enabled nvidia-persistenced.service"),
_ => error!("An error ocurred while enabling service"),
Ok(s) => error!(
"nvidia-persistenced.service enable failed with exit code: {}",
s
),
Err(e) => error!("Failed to run systemctl: {}", e),
}
if no_reboot {
@@ -914,9 +939,13 @@ pub fn execute_local(cmd: &GpuCommands) {
GpuCommands::CacheDelete => {
assert_root();
if Path::new(CACHE_FILE_PATH).exists() {
let _ = fs::remove_file(CACHE_FILE_PATH);
if let Some(parent) = Path::new(CACHE_FILE_PATH).parent() {
let _ = fs::remove_dir(parent);
if let Err(e) = fs::remove_file(CACHE_FILE_PATH) {
error!("Failed to remove cache file: {}", e);
}
if let Some(parent) = Path::new(CACHE_FILE_PATH).parent()
&& let Err(e) = fs::remove_dir(parent)
{
log::debug!("Failed to remove cache directory: {}", e);
}
}
}
@@ -936,9 +965,13 @@ pub fn execute_local(cmd: &GpuCommands) {
cleanup();
if Path::new(CACHE_FILE_PATH).exists() {
let _ = fs::remove_file(CACHE_FILE_PATH);
if let Some(parent) = Path::new(CACHE_FILE_PATH).parent() {
let _ = fs::remove_dir(parent);
if let Err(e) = fs::remove_file(CACHE_FILE_PATH) {
error!("Failed to remove cache file: {}", e);
}
if let Some(parent) = Path::new(CACHE_FILE_PATH).parent()
&& let Err(e) = fs::remove_dir(parent)
{
log::debug!("Failed to remove cache directory: {}", e);
}
}
rebuild_initramfs();
+31 -10
View File
@@ -1,5 +1,5 @@
use crate::utils::system::{assert_root, create_file};
use log::info;
use log::{error, info};
use std::process::Command;
// No longer needed: all privileged operations are now handled by the lapctld daemon via D-Bus.
@@ -76,8 +76,20 @@ WantedBy=multi-user.target
pub fn execute() {
assert_root();
let current_exe = std::env::current_exe().expect("Failed to get current executable path");
let exe_path = current_exe.to_str().expect("Invalid executable path");
let current_exe = match std::env::current_exe() {
Ok(exe) => exe,
Err(e) => {
error!("Failed to get current executable path: {}", e);
std::process::exit(1);
}
};
let exe_path = match current_exe.to_str() {
Some(p) => p,
None => {
error!("Executable path contains invalid UTF-8");
std::process::exit(1);
}
};
println!("Found lapctl at: {}", exe_path);
println!("Installing lapctl configuration with dynamic paths...");
@@ -105,23 +117,32 @@ pub fn execute() {
println!("Activating background daemon (lapctld)...");
// Reload systemd to recognize the new service
let _ = Command::new("systemctl").arg("daemon-reload").status();
if let Err(e) = Command::new("systemctl").arg("daemon-reload").status() {
error!("Failed to run systemctl daemon-reload: {}", e);
println!("You may need to run 'systemctl daemon-reload' manually.");
}
// Enable and start the daemon
let status = Command::new("systemctl")
.args(["enable", "--now", "lapctld"])
.status();
let daemon_ok = if let Ok(s) = status {
if s.success() {
let daemon_ok = match status {
Ok(s) if s.success() => {
info!("lapctld daemon enabled and started.");
true
} else {
log::error!("Failed to enable/start lapctld daemon.");
}
Ok(s) => {
log::error!(
"systemctl enable --now lapctld failed with exit code: {}",
s
);
false
}
Err(e) => {
log::error!("Failed to run systemctl: {}", e);
false
}
} else {
false
};
if daemon_ok {