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:
2 files changed
+81
-27
No files matched your search
+50
-17
@@ -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();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in new issue
Block a user