sal/src/virt/rfs/mount.rs
2025-04-05 19:00:59 +02:00

142 lines
4.7 KiB
Rust

use super::{
error::RfsError,
cmd::execute_rfs_command,
types::Mount,
};
/// List all mounted filesystems
///
/// # Returns
///
/// * `Result<Vec<Mount>, RfsError>` - List of mounts or error
pub fn list_mounts() -> Result<Vec<Mount>, RfsError> {
// Execute the list command
let result = execute_rfs_command(&["list", "--json"])?;
// Parse the JSON output
match serde_json::from_str::<serde_json::Value>(&result.stdout) {
Ok(json) => {
if let serde_json::Value::Array(mounts_json) = json {
let mut mounts = Vec::new();
for mount_json in mounts_json {
// Extract mount ID
let id = match mount_json.get("id").and_then(|v| v.as_str()) {
Some(id) => id.to_string(),
None => return Err(RfsError::ListFailed("Missing mount ID".to_string())),
};
// Extract source
let source = match mount_json.get("source").and_then(|v| v.as_str()) {
Some(source) => source.to_string(),
None => return Err(RfsError::ListFailed("Missing source".to_string())),
};
// Extract target
let target = match mount_json.get("target").and_then(|v| v.as_str()) {
Some(target) => target.to_string(),
None => return Err(RfsError::ListFailed("Missing target".to_string())),
};
// Extract filesystem type
let fs_type = match mount_json.get("type").and_then(|v| v.as_str()) {
Some(fs_type) => fs_type.to_string(),
None => return Err(RfsError::ListFailed("Missing filesystem type".to_string())),
};
// Extract options
let options = match mount_json.get("options").and_then(|v| v.as_array()) {
Some(options_array) => {
let mut options_vec = Vec::new();
for option_value in options_array {
if let Some(option_str) = option_value.as_str() {
options_vec.push(option_str.to_string());
}
}
options_vec
},
None => Vec::new(), // Empty vector if no options found
};
// Create Mount struct and add to vector
mounts.push(Mount {
id,
source,
target,
fs_type,
options,
});
}
Ok(mounts)
} else {
Err(RfsError::ListFailed("Expected JSON array".to_string()))
}
},
Err(e) => {
Err(RfsError::ListFailed(format!("Failed to parse mount list JSON: {}", e)))
}
}
}
/// Unmount a filesystem by target path
///
/// # Arguments
///
/// * `target` - Target mount point
///
/// # Returns
///
/// * `Result<(), RfsError>` - Success or error
pub fn unmount(target: &str) -> Result<(), RfsError> {
// Execute the unmount command
let result = execute_rfs_command(&["unmount", target])?;
// Check for errors
if !result.success {
return Err(RfsError::UnmountFailed(format!("Failed to unmount {}: {}", target, result.stderr)));
}
Ok(())
}
/// Unmount all filesystems
///
/// # Returns
///
/// * `Result<(), RfsError>` - Success or error
pub fn unmount_all() -> Result<(), RfsError> {
// Execute the unmount all command
let result = execute_rfs_command(&["unmount", "--all"])?;
// Check for errors
if !result.success {
return Err(RfsError::UnmountFailed(format!("Failed to unmount all filesystems: {}", result.stderr)));
}
Ok(())
}
/// Get information about a mounted filesystem
///
/// # Arguments
///
/// * `target` - Target mount point
///
/// # Returns
///
/// * `Result<Mount, RfsError>` - Mount information or error
pub fn get_mount_info(target: &str) -> Result<Mount, RfsError> {
// Get all mounts
let mounts = list_mounts()?;
// Find the mount with the specified target
for mount in mounts {
if mount.target == target {
return Ok(mount);
}
}
// Mount not found
Err(RfsError::Other(format!("No mount found at {}", target)))
}