Skip to content

Commit

Permalink
partially fix mount
Browse files Browse the repository at this point in the history
  • Loading branch information
doriancodes committed Dec 18, 2024
1 parent 899fd5e commit a9d5e03
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 87 deletions.
33 changes: 23 additions & 10 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ use anyhow::Result;
use clap::{Parser, Subcommand};
use froggr::modules::namespace::BindMode;
use froggr::modules::session::SessionManager;
use log::{error, info};
use log::{debug, error, info};
use std::path::PathBuf;
use env_logger;

#[derive(Parser)]
#[command(author, version, about, long_about = None)]
Expand Down Expand Up @@ -65,7 +66,17 @@ enum Commands {

#[tokio::main]
async fn main() -> Result<()> {
// Initialize the logger at the start of main
env_logger::init();

info!("Froggr starting up");

let cli = Cli::parse();

if cli.verbose {
debug!("Verbose mode enabled");
}

let session_manager = SessionManager::new()?;

match &cli.command {
Expand Down Expand Up @@ -93,29 +104,31 @@ async fn main() -> Result<()> {
std::thread::sleep(std::time::Duration::from_secs(1));
}
Commands::Mount { source, mount_point, node_id } => {
info!("Starting mount operation");
info!("Starting mount operation in process {}", std::process::id());
let session_manager = SessionManager::new()?;
info!("Created session manager");

let session_id = session_manager.create_session(mount_point.clone())?;
info!("Created session: {}", session_id);
println!("Created new session: {}", session_id);

if let Some(session_info) = session_manager.get_session(&session_id)? {
info!("Found session with PID {}", session_info.pid);
if let Some(session) = session_manager.get_session(&session_id)? {
info!("Found session with PID {}", session.pid);
info!("Sending mount command...");
session_manager.send_mount_command(
&session_id,
source.clone(),
mount_point.clone(),
node_id.clone()
)?;
info!("Mount command sent to session");

std::thread::sleep(std::time::Duration::from_secs(1));

if let Some(updated_info) = session_manager.get_session(&session_id)? {
info!("Current mounts: {:?}", updated_info.mounts);
}
} else {
error!("No session found for mount operation");
}

info!("Waiting for mount operation to complete");
std::thread::sleep(std::time::Duration::from_secs(1));
info!("Mount operation completed");
}
Commands::Session { list, kill, purge, session_id } => {
if *list {
Expand Down
75 changes: 63 additions & 12 deletions src/modules/mount.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@ use super::constants::BLOCK_SIZE;
use super::namespace::{BindMode, NamespaceEntry};
use super::proto::{BoundEntry, NineP};
use anyhow::{anyhow, Result};
use fuser::{FileAttr, FileType};
use fuser::{FileAttr, FileType, MountOption};
use std::collections::HashMap;
use std::collections::VecDeque;
use std::ffi::CString;
use std::ffi::OsString;
use std::fs;
use std::path::Path;
use std::time::UNIX_EPOCH;
use log::{info, debug, warn};
use log::{info, debug, warn, error};
use std::cell::RefCell;
use std::sync::Arc;
use crate::session::Session;
use std::thread;

#[cfg(target_os = "macos")]
extern "C" {
Expand All @@ -38,7 +39,7 @@ extern "C" {
}

/// Manages filesystem mounting and binding operations.
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct FilesystemManager {
/// The underlying 9P filesystem implementation.
pub fs: NineP,
Expand Down Expand Up @@ -335,47 +336,65 @@ impl FilesystemManager {
pub fn mount(&self, source: &Path, target: &Path, node_id: &str) -> Result<()> {
info!("Mounting {} to {} for node {}", source.display(), target.display(), node_id);

// Resolve paths
// Check if we have a current session
debug!("Checking current session...");
if let Some(session) = self.get_session() {
info!("Found existing session: {:?}", session);
} else {
warn!("No current session found before mount");
}

debug!("Checking paths...");
let abs_source = fs::canonicalize(source)?;
let abs_target = fs::canonicalize(target)?;

info!("Resolved paths - source: {:?}, target: {:?}", abs_source, abs_target);

// Verify paths exist
if !abs_source.exists() {
error!("Source path does not exist: {:?}", abs_source);
return Err(anyhow!("Source path does not exist: {:?}", abs_source));
}
if !abs_target.exists() {
error!("Target path does not exist: {:?}", abs_target);
return Err(anyhow!("Target path does not exist: {:?}", abs_target));
}

// Create mount entry
thread::sleep(std::time::Duration::from_millis(100));

// Update namespace first
debug!("Updating namespace...");
let entry = NamespaceEntry {
source: abs_source.clone(),
target: abs_target.clone(),
bind_mode: BindMode::Before, // Default mode for mounts
bind_mode: BindMode::Before,
remote_node: Some(node_id.to_string()),
};

// Update namespace
debug!("Updating namespace...");
let mut namespace = self.fs.namespace_manager.namespace.write().unwrap();
namespace
.entry(abs_target.clone())
.or_insert_with(Vec::new)
.push(entry);

// Perform the mount operation
self.mount_directory(abs_target.to_str().unwrap(), &abs_source)?;
// Update bindings
self.update_bindings(abs_target.to_str().unwrap(), &abs_source)?;

// Notify session of successful mount
info!("Mount operation successful, notifying session");
if let Some(session) = FilesystemManager::get_current_session() {
if let Some(session) = self.get_session() {
info!("Found current session, sending notification");
session.notify_mount_success(source.to_path_buf(), target.to_path_buf())?;
info!("Mount success notification sent");
match session.notify_mount_success(source.to_path_buf(), target.to_path_buf()) {
Ok(_) => info!("Mount success notification sent"),
Err(e) => warn!("Failed to send mount notification: {:?}", e),
}
} else {
warn!("No current session found for mount notification");
}

info!("Mount operation completed successfully");
Ok(())
}

Expand Down Expand Up @@ -503,6 +522,38 @@ impl FilesystemManager {
}
Ok(())
}

fn update_bindings(&self, dir_path: &str, source_path: &Path) -> Result<()> {
debug!("Updating bindings for: {} from source: {:?}", dir_path, source_path);

let mut bindings = self.fs.namespace_manager.bindings.lock().unwrap();
let mut next_inode = self.fs.namespace_manager.next_inode.lock().unwrap();

// Convert paths to absolute paths
let abs_source = fs::canonicalize(source_path)?;
let abs_target = fs::canonicalize(Path::new(dir_path))?;

// Clear existing bindings but keep root
bindings.retain(|&ino, _| ino == 1);

// Read source directory recursively
self.read_directory_entries_recursive(
&abs_source,
&abs_source,
1,
&mut next_inode,
&mut bindings,
)?;

info!("Final bindings: {:?}", bindings.keys().collect::<Vec<_>>());
for (inode, (name, entry)) in bindings.iter() {
debug!(
"inode: {}, name: {:?}, kind: {:?}",
inode, name, entry.attr.kind
);
}
Ok(())
}
}

#[cfg(test)]
Expand Down
Loading

0 comments on commit a9d5e03

Please sign in to comment.