diff --git a/clients/filesystem-fuse/Cargo.toml b/clients/filesystem-fuse/Cargo.toml index 3760bd5285f..0a84c11bb8c 100644 --- a/clients/filesystem-fuse/Cargo.toml +++ b/clients/filesystem-fuse/Cargo.toml @@ -35,6 +35,7 @@ name = "gvfs_fuse" [dependencies] async-trait = "0.1" bytes = "1.6.0" +chrono = "0.4.39" config = "0.13" dashmap = "6.1.0" fuse3 = { version = "0.8.1", "features" = ["tokio-runtime", "unprivileged"] } @@ -46,6 +47,7 @@ opendal = { version = "0.46.0", features = ["services-s3"] } reqwest = { version = "0.12.9", features = ["json"] } serde = { version = "1.0.216", features = ["derive"] } tokio = { version = "1.38.0", features = ["full"] } +tracing = "0.1.41" tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } urlencoding = "2.1.3" diff --git a/clients/filesystem-fuse/conf/gvfs_fuse.toml b/clients/filesystem-fuse/conf/gvfs_fuse.toml index 4bde0e9e1bd..243d8730e80 100644 --- a/clients/filesystem-fuse/conf/gvfs_fuse.toml +++ b/clients/filesystem-fuse/conf/gvfs_fuse.toml @@ -20,6 +20,7 @@ file_mask = 0o600 dir_mask = 0o700 fs_type = "memory" +fuse_debug=true [fuse.properties] diff --git a/clients/filesystem-fuse/src/config.rs b/clients/filesystem-fuse/src/config.rs index 17908fd08fc..f6d519b17c1 100644 --- a/clients/filesystem-fuse/src/config.rs +++ b/clients/filesystem-fuse/src/config.rs @@ -265,6 +265,8 @@ pub struct FuseConfig { #[serde(default)] pub fs_type: String, #[serde(default)] + pub fuse_debug: bool, + #[serde(default)] pub config_path: String, #[serde(default)] pub properties: HashMap, diff --git a/clients/filesystem-fuse/src/filesystem.rs b/clients/filesystem-fuse/src/filesystem.rs index dcf35f8ebca..ffa85c67e51 100644 --- a/clients/filesystem-fuse/src/filesystem.rs +++ b/clients/filesystem-fuse/src/filesystem.rs @@ -145,6 +145,7 @@ pub(crate) trait PathFileSystem: Send + Sync { } // FileSystemContext is the system environment for the fuse file system. +#[derive(Debug)] pub(crate) struct FileSystemContext { // system user id pub(crate) uid: u32, diff --git a/clients/filesystem-fuse/src/fuse_api_handle.rs b/clients/filesystem-fuse/src/fuse_api_handle.rs index 15679a222bd..ca46d47501d 100644 --- a/clients/filesystem-fuse/src/fuse_api_handle.rs +++ b/clients/filesystem-fuse/src/fuse_api_handle.rs @@ -53,7 +53,7 @@ impl FuseApiHandle { } } - async fn get_modified_file_stat( + pub async fn get_modified_file_stat( &self, file_id: u64, size: Option, @@ -64,15 +64,15 @@ impl FuseApiHandle { if let Some(size) = size { file_stat.size = size; - }; + } if let Some(atime) = atime { file_stat.atime = atime; - }; + } if let Some(mtime) = mtime { file_stat.mtime = mtime; - }; + } Ok(file_stat) } @@ -117,6 +117,7 @@ impl Filesystem for FuseApiHandle { } let file_stat = self.fs.stat(inode).await?; + Ok(ReplyAttr { ttl: self.default_ttl, attr: fstat_to_file_attr(&file_stat, &self.fs_context), @@ -256,7 +257,7 @@ impl Filesystem for FuseApiHandle { } type DirEntryStream<'a> - = BoxStream<'a, fuse3::Result> + = BoxStream<'a, fuse3::Result> where T: 'a; @@ -336,7 +337,7 @@ impl Filesystem for FuseApiHandle { } type DirEntryPlusStream<'a> - = BoxStream<'a, fuse3::Result> + = BoxStream<'a, fuse3::Result> where T: 'a; diff --git a/clients/filesystem-fuse/src/fuse_api_handle_debug.rs b/clients/filesystem-fuse/src/fuse_api_handle_debug.rs new file mode 100644 index 00000000000..d19fc4cc328 --- /dev/null +++ b/clients/filesystem-fuse/src/fuse_api_handle_debug.rs @@ -0,0 +1,584 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +use crate::config::AppConfig; +use crate::filesystem::{FileSystemContext, RawFileSystem}; +use crate::fuse_api_handle::FuseApiHandle; +use chrono::DateTime; +use fuse3::path::prelude::{ReplyData, ReplyOpen, ReplyStatFs, ReplyWrite}; +use fuse3::path::Request; +use fuse3::raw::prelude::{ + FileAttr, ReplyAttr, ReplyCreated, ReplyDirectory, ReplyDirectoryPlus, ReplyEntry, ReplyInit, +}; +use fuse3::raw::reply::{DirectoryEntry, DirectoryEntryPlus}; +use fuse3::raw::Filesystem; +use fuse3::{Inode, SetAttr, Timestamp}; +use futures_util::stream::BoxStream; +use std::ffi::OsStr; +use std::fmt::Write; +use tracing::{debug, error}; + +/// A macro to log the result of an asynchronous method call in the context of FUSE operations. +/// +/// This macro provides three variants for logging: +/// 1. Without logging the reply (logs only the method status). +/// 2. With default `Debug` formatting for the reply. +/// 3. With a customizable formatting function for the reply. +/// +/// # Usage +/// +/// ```ignore +/// // No reply printing +/// log_result!(method_call, "method_name", req); +/// +/// // With default Debug formatting for the reply +/// log_result!(method_call, "method_name", req, debug); +/// +/// // With a custom formatting function for the reply +/// log_result!(method_call, "method_name", req, custom_format_fn); +/// ``` +/// +/// # Arguments +/// +/// - `$method_call`: The asynchronous method call to execute and log. +/// - `$method_name`: A string representing the name of the method for logging purposes. +/// - `$req`: The incoming FUSE request associated with the method call. +/// - `$format_reply_fn`: (Optional) A custom formatting function to describe the reply more specifically. +macro_rules! log_result { + // No reply printing + ($method_call:expr, $method_name:expr, $req:ident) => { + match $method_call.await { + Ok(reply) => { + debug!($req.unique, concat!($method_name, " completed")); + Ok(reply) + } + Err(e) => { + error!($req.unique, ?e, concat!($method_name, " failed")); + Err(e) + } + } + }; + + // Default Debug formatting + ($method_call:expr, $method_name:expr, $req:ident, debug) => { + match $method_call.await { + Ok(reply) => { + debug!($req.unique, ?reply, concat!($method_name, " completed")); + Ok(reply) + } + Err(e) => { + error!($req.unique, ?e, concat!($method_name, " failed")); + Err(e) + } + } + }; + + // Format reply with custom format function + ($method_call:expr, $method_name:expr, $req:ident, $format_reply_fn:ident) => { + match $method_call.await { + Ok(reply) => { + debug!($req.unique, reply = %$format_reply_fn(&reply), concat!($method_name, " completed")); + Ok(reply) + } + Err(e) => { + error!($req.unique, ?e, concat!($method_name, " failed")); + Err(e) + } + } + }; +} + +/// Convert `ReplyAttr` to descriptive string. +/// +/// Example: `ttl: 1s, FileAttr: { ino: 10000, size: 0, blocks: 0, atime: "2025-01-16 02:42:52.600436", mtime: "2025-01-16 02:42:52.600436", ctime: "2025-01-16 02:42:52.600436", crtime: "2025-01-16 02:42:52.600436", kind: RegularFile, perm: 600, nlink: 1, uid: 501, gid: 20, rdev: 0, flags: 0, blksize: 8192 }` +fn reply_attr_to_desc_str(reply_attr: &ReplyAttr) -> String { + let mut output = String::new(); + + write!(output, "ttl: {:?}, ", reply_attr.ttl).unwrap(); + write!( + output, + "FileAttr: {}", + file_attr_to_desc_str(&reply_attr.attr) + ) + .unwrap(); + + output +} + +/// Convert `ReplyEntry` to descriptive string. +/// +/// Example: `ttl: 1s, FileAttr: { ino: 10001, size: 0, blocks: 1, atime: "2025-01-16 02:42:52.606512", mtime: "2025-01-16 02:42:52.606512", ctime: "2025-01-16 02:42:52.606512", crtime: "2025-01-16 02:42:52.606512", kind: Directory, perm: 700, nlink: 0, uid: 501, gid: 20, rdev: 0, flags: 0, blksize: 8192 }, generation: 0` +fn reply_entry_to_desc_str(reply_entry: &ReplyEntry) -> String { + let mut output = String::new(); + + write!(output, "ttl: {:?}, ", reply_entry.ttl).unwrap(); + write!( + output, + "FileAttr: {}, ", + file_attr_to_desc_str(&reply_entry.attr) + ) + .unwrap(); + write!(output, "generation: {}", reply_entry.generation).unwrap(); + + output +} + +/// Convert `ReplyCreated` to descriptive string. +/// +/// Example: `ttl: 1s, FileAttr: { ino: 10000, size: 0, blocks: 1, atime: "2025-01-16 02:47:32.126592", mtime: "2025-01-16 02:47:32.126592", ctime: "2025-01-16 02:47:32.126592", crtime: "2025-01-16 02:47:32.126592", kind: RegularFile, perm: 600, nlink: 0, uid: 501, gid: 20, rdev: 0, flags: 0, blksize: 8192 }, generation: 0, fh: 1` +fn reply_created_to_desc_str(reply_created: &ReplyCreated) -> String { + let mut output = String::new(); + + write!(output, "ttl: {:?}, ", reply_created.ttl).unwrap(); + write!( + output, + "FileAttr: {}, ", + file_attr_to_desc_str(&reply_created.attr) + ) + .unwrap(); + write!(output, "generation: {}, ", reply_created.generation).unwrap(); + write!(output, "fh: {}", reply_created.fh).unwrap(); + + output +} + +/// Convert `FileAttr` to descriptive string. +/// +/// Example: `{ ino: 10000, size: 0, blocks: 1, atime: "2025-01-10 22:53:45.491337", mtime: "2025-01-10 22:53:45.491337", ctime: "2025-01-10 22:53:45.491337", crtime: "2025-01-10 22:53:45.491337", kind: RegularFile, perm: 384, nlink: 0, uid: 501, gid: 20, rdev: 0, flags: 0, blksize: 8192 }` +fn file_attr_to_desc_str(attr: &FileAttr) -> String { + let mut output = String::new(); + + write!(output, "{{ ").unwrap(); + + write!(output, "ino: {}, ", attr.ino).unwrap(); + write!(output, "size: {}, ", attr.size).unwrap(); + write!(output, "blocks: {}, ", attr.blocks).unwrap(); + write!( + output, + "atime: {:?}, ", + timestamp_to_desc_string(attr.atime) + ) + .unwrap(); + write!( + output, + "mtime: {:?}, ", + timestamp_to_desc_string(attr.mtime) + ) + .unwrap(); + write!( + output, + "ctime: {:?}, ", + timestamp_to_desc_string(attr.ctime) + ) + .unwrap(); + #[cfg(target_os = "macos")] + { + write!( + output, + "crtime: {:?}, ", + timestamp_to_desc_string(attr.crtime) + ) + .unwrap(); + } + write!(output, "kind: {:?}, ", attr.kind).unwrap(); + write!(output, "perm: {:o}, ", attr.perm).unwrap(); + write!(output, "nlink: {}, ", attr.nlink).unwrap(); + write!(output, "uid: {}, ", attr.uid).unwrap(); + write!(output, "gid: {}, ", attr.gid).unwrap(); + write!(output, "rdev: {}, ", attr.rdev).unwrap(); + #[cfg(target_os = "macos")] + { + write!(output, "flags: {}, ", attr.flags).unwrap(); + } + write!(output, "blksize: {}", attr.blksize).unwrap(); + + write!(output, " }}").unwrap(); + + output +} + +/// Convert `Timestamp` to descriptive string. +/// +/// Example output: "2025-01-07 23:01:30.531699" +fn timestamp_to_desc_string(tstmp: Timestamp) -> String { + DateTime::from_timestamp(tstmp.sec, tstmp.nsec) + .unwrap() + .naive_utc() + .to_string() +} + +pub(crate) struct FuseApiHandleDebug { + inner: FuseApiHandle, +} + +impl FuseApiHandleDebug { + pub fn new(fs: T, _config: &AppConfig, context: FileSystemContext) -> Self { + Self { + inner: FuseApiHandle::new(fs, _config, context), + } + } +} + +impl Filesystem for FuseApiHandleDebug { + async fn init(&self, req: Request) -> fuse3::Result { + debug!(req.unique, ?req, "init"); + log_result!(self.inner.init(req), "init", req, debug) + } + + async fn destroy(&self, req: Request) { + debug!(req.unique, ?req, "destroy started"); + self.inner.destroy(req).await; + debug!(req.unique, "destroy completed"); + } + + async fn lookup(&self, req: Request, parent: Inode, name: &OsStr) -> fuse3::Result { + let parent_stat = self + .inner + .get_modified_file_stat(parent, Option::None, Option::None, Option::None) + .await?; + debug!(req.unique, ?req, parent = ?parent_stat.name, ?name, "lookup started"); + + log_result!( + self.inner.lookup(req, parent, name), + "lookup", + req, + reply_entry_to_desc_str + ) + } + + async fn getattr( + &self, + req: Request, + inode: Inode, + fh: Option, + flags: u32, + ) -> fuse3::Result { + let stat = self + .inner + .get_modified_file_stat(inode, Option::None, Option::None, Option::None) + .await?; + debug!(req.unique, ?req, "filename" = ?stat.name, ?fh, ?flags, "getattr started"); + + log_result!( + self.inner.getattr(req, inode, fh, flags), + "getattr", + req, + reply_attr_to_desc_str + ) + } + + async fn setattr( + &self, + req: Request, + inode: Inode, + fh: Option, + set_attr: SetAttr, + ) -> fuse3::Result { + let stat = self + .inner + .get_modified_file_stat(inode, Option::None, Option::None, Option::None) + .await?; + debug!(req.unique, ?req, "filename" = ?stat.name, ?fh, ?set_attr, "setattr started"); + + log_result!( + self.inner.setattr(req, inode, fh, set_attr), + "setattr", + req, + reply_attr_to_desc_str + ) + } + + async fn mkdir( + &self, + req: Request, + parent: Inode, + name: &OsStr, + mode: u32, + umask: u32, + ) -> fuse3::Result { + let parent_stat = self + .inner + .get_modified_file_stat(parent, Option::None, Option::None, Option::None) + .await?; + debug!( + req.unique, + ?req, + parent = ?parent_stat.name, + ?name, + mode, + umask, + "mkdir started" + ); + + log_result!( + self.inner.mkdir(req, parent, name, mode, umask), + "mkdir", + req, + reply_entry_to_desc_str + ) + } + + async fn unlink(&self, req: Request, parent: Inode, name: &OsStr) -> fuse3::Result<()> { + let parent_stat = self + .inner + .get_modified_file_stat(parent, Option::None, Option::None, Option::None) + .await?; + debug!(req.unique, ?req, parent = ?parent_stat.name, ?name, "unlink started"); + + log_result!(self.inner.unlink(req, parent, name), "unlink", req) + } + + async fn rmdir(&self, req: Request, parent: Inode, name: &OsStr) -> fuse3::Result<()> { + let parent_stat = self + .inner + .get_modified_file_stat(parent, Option::None, Option::None, Option::None) + .await?; + debug!(req.unique, ?req, parent = ?parent_stat.name, ?name, "rmdir started"); + + log_result!(self.inner.rmdir(req, parent, name), "rmdir", req) + } + + async fn open(&self, req: Request, inode: Inode, flags: u32) -> fuse3::Result { + let stat = self + .inner + .get_modified_file_stat(inode, Option::None, Option::None, Option::None) + .await?; + debug!(req.unique, ?req, "filename" = ?stat.name, ?flags, "open started"); + + log_result!(self.inner.open(req, inode, flags), "open", req, debug) + } + + async fn read( + &self, + req: Request, + inode: Inode, + fh: u64, + offset: u64, + size: u32, + ) -> fuse3::Result { + let stat = self + .inner + .get_modified_file_stat(inode, Option::None, Option::None, Option::None) + .await?; + debug!( + req.unique, + ?req, + "filename" = ?stat.name, + ?fh, + ?offset, + ?size, + "read started" + ); + + log_result!(self.inner.read(req, inode, fh, offset, size), "read", req) + } + + async fn write( + &self, + req: Request, + inode: Inode, + fh: u64, + offset: u64, + data: &[u8], + write_flags: u32, + flags: u32, + ) -> fuse3::Result { + let stat = self + .inner + .get_modified_file_stat(inode, Option::None, Option::None, Option::None) + .await?; + debug!( + req.unique, + ?req, + "filename" = ?stat.name, + ?fh, + ?offset, + data_len = data.len(), + ?write_flags, + ?flags, + "write started" + ); + + log_result!( + self.inner + .write(req, inode, fh, offset, data, write_flags, flags), + "write", + req + ) + } + + async fn statfs(&self, req: Request, inode: Inode) -> fuse3::Result { + let stat = self + .inner + .get_modified_file_stat(inode, Option::None, Option::None, Option::None) + .await?; + debug!(req.unique, ?req, "filename" = ?stat.name, "statfs started"); + + log_result!(self.inner.statfs(req, inode), "statfs", req, debug) + } + + async fn release( + &self, + req: Request, + inode: Inode, + fh: u64, + flags: u32, + lock_owner: u64, + flush: bool, + ) -> fuse3::Result<()> { + let stat = self + .inner + .get_modified_file_stat(inode, Option::None, Option::None, Option::None) + .await?; + debug!( + req.unique, + ?req, + "pathname" = ?stat.name, + ?fh, + ?flags, + ?lock_owner, + ?flush, + "release started" + ); + + log_result!( + self.inner.release(req, inode, fh, flags, lock_owner, flush), + "release", + req + ) + } + + async fn opendir(&self, req: Request, inode: Inode, flags: u32) -> fuse3::Result { + let stat = self + .inner + .get_modified_file_stat(inode, Option::None, Option::None, Option::None) + .await?; + debug!(req.unique, ?req, "dirname" = ?stat.name, ?flags, "opendir started"); + + log_result!(self.inner.opendir(req, inode, flags), "opendir", req, debug) + } + + type DirEntryStream<'a> = BoxStream<'a, fuse3::Result> + where + T: 'a; + + #[allow(clippy::needless_lifetimes)] + async fn readdir<'a>( + &'a self, + req: Request, + parent: Inode, + fh: u64, + offset: i64, + ) -> fuse3::Result>> { + let stat = self + .inner + .get_modified_file_stat(parent, Option::None, Option::None, Option::None) + .await?; + debug!( + req.unique, + ?req, + parent = ?stat.name, + ?fh, + ?offset, + "readdir started" + ); + + log_result!(self.inner.readdir(req, parent, fh, offset), "readdir", req) + } + + async fn releasedir( + &self, + req: Request, + inode: Inode, + fh: u64, + flags: u32, + ) -> fuse3::Result<()> { + let stat = self + .inner + .get_modified_file_stat(inode, Option::None, Option::None, Option::None) + .await?; + debug!(req.unique, ?req, "dirname" = ?stat.name, ?fh, ?flags, "releasedir started"); + + log_result!( + self.inner.releasedir(req, inode, fh, flags), + "releasedir", + req + ) + } + + async fn create( + &self, + req: Request, + parent: Inode, + name: &OsStr, + mode: u32, + flags: u32, + ) -> fuse3::Result { + let parent_stat = self + .inner + .get_modified_file_stat(parent, Option::None, Option::None, Option::None) + .await?; + debug!( + req.unique, + ?req, + parent = ?parent_stat.name, + "filename" = ?name, + ?mode, + ?flags, + "create started" + ); + + log_result!( + self.inner.create(req, parent, name, mode, flags), + "create", + req, + reply_created_to_desc_str + ) + } + + type DirEntryPlusStream<'a> = BoxStream<'a, fuse3::Result> + where + T: 'a; + + #[allow(clippy::needless_lifetimes)] + async fn readdirplus<'a>( + &'a self, + req: Request, + parent: Inode, + fh: u64, + offset: u64, + lock_owner: u64, + ) -> fuse3::Result>> { + debug!( + req.unique, + ?req, + ?parent, + ?fh, + ?offset, + ?lock_owner, + "readdirplus started" + ); + + log_result!( + self.inner.readdirplus(req, parent, fh, offset, lock_owner), + "readdirplus", + req + ) + } +} diff --git a/clients/filesystem-fuse/src/gvfs_fuse.rs b/clients/filesystem-fuse/src/gvfs_fuse.rs index 88079e99b91..69845643fc9 100644 --- a/clients/filesystem-fuse/src/gvfs_fuse.rs +++ b/clients/filesystem-fuse/src/gvfs_fuse.rs @@ -21,6 +21,7 @@ use crate::default_raw_filesystem::DefaultRawFileSystem; use crate::error::ErrorCode::UnSupportedFilesystem; use crate::filesystem::FileSystemContext; use crate::fuse_api_handle::FuseApiHandle; +use crate::fuse_api_handle_debug::FuseApiHandleDebug; use crate::fuse_server::FuseServer; use crate::gravitino_fileset_filesystem::GravitinoFilesetFileSystem; use crate::gvfs_creator::create_gvfs_filesystem; @@ -38,6 +39,8 @@ pub(crate) enum CreateFileSystemResult { Gvfs(GravitinoFilesetFileSystem), FuseMemoryFs(FuseApiHandle>), FuseGvfs(FuseApiHandle>), + FuseMemoryFsWithDebug(FuseApiHandleDebug>), + FuseGvfsWithDebug(FuseApiHandleDebug>), None, } @@ -56,7 +59,9 @@ pub async fn mount(mount_to: &str, mount_from: &str, config: &AppConfig) -> Gvfs let fs = create_fuse_fs(mount_from, config).await?; match fs { CreateFileSystemResult::FuseMemoryFs(vfs) => svr.start(vfs).await?, + CreateFileSystemResult::FuseMemoryFsWithDebug(vfs) => svr.start(vfs).await?, CreateFileSystemResult::FuseGvfs(vfs) => svr.start(vfs).await?, + CreateFileSystemResult::FuseGvfsWithDebug(vfs) => svr.start(vfs).await?, _ => return Err(UnSupportedFilesystem.to_error("Unsupported filesystem type".to_string())), } Ok(()) @@ -93,6 +98,14 @@ pub async fn create_raw_fs( ) -> GvfsResult { match path_fs { CreateFileSystemResult::Memory(fs) => { + if config.fuse.fuse_debug { + let fs = FuseApiHandleDebug::new( + DefaultRawFileSystem::new(fs, config, &fs_context), + config, + fs_context, + ); + return Ok(CreateFileSystemResult::FuseMemoryFsWithDebug(fs)); + } let fs = FuseApiHandle::new( DefaultRawFileSystem::new(fs, config, &fs_context), config, @@ -101,6 +114,14 @@ pub async fn create_raw_fs( Ok(CreateFileSystemResult::FuseMemoryFs(fs)) } CreateFileSystemResult::Gvfs(fs) => { + if config.fuse.fuse_debug { + let fs = FuseApiHandleDebug::new( + DefaultRawFileSystem::new(fs, config, &fs_context), + config, + fs_context, + ); + return Ok(CreateFileSystemResult::FuseGvfsWithDebug(fs)); + } let fs = FuseApiHandle::new( DefaultRawFileSystem::new(fs, config, &fs_context), config, diff --git a/clients/filesystem-fuse/src/lib.rs b/clients/filesystem-fuse/src/lib.rs index 41a9a5335d5..61050f1733b 100644 --- a/clients/filesystem-fuse/src/lib.rs +++ b/clients/filesystem-fuse/src/lib.rs @@ -24,6 +24,7 @@ mod default_raw_filesystem; mod error; mod filesystem; mod fuse_api_handle; +mod fuse_api_handle_debug; mod fuse_server; mod gravitino_client; mod gravitino_fileset_filesystem; diff --git a/clients/filesystem-fuse/src/main.rs b/clients/filesystem-fuse/src/main.rs index 3534e033465..4e517c76b37 100644 --- a/clients/filesystem-fuse/src/main.rs +++ b/clients/filesystem-fuse/src/main.rs @@ -24,7 +24,7 @@ use tokio::signal; #[tokio::main] async fn main() -> fuse3::Result<()> { - tracing_subscriber::fmt().init(); + tracing_subscriber::fmt::init(); // todo need inmprove the args parsing let args: Vec = std::env::args().collect(); diff --git a/clients/filesystem-fuse/tests/conf/gvfs_fuse_memory.toml b/clients/filesystem-fuse/tests/conf/gvfs_fuse_memory.toml index 0ec447cd087..c6eb0109a18 100644 --- a/clients/filesystem-fuse/tests/conf/gvfs_fuse_memory.toml +++ b/clients/filesystem-fuse/tests/conf/gvfs_fuse_memory.toml @@ -20,6 +20,7 @@ file_mask= 0o600 dir_mask= 0o700 fs_type = "memory" +fuse_debug = true [fuse.properties] key1 = "value1" diff --git a/clients/filesystem-fuse/tests/fuse_test.rs b/clients/filesystem-fuse/tests/fuse_test.rs index 41e385c49f1..ab09644d038 100644 --- a/clients/filesystem-fuse/tests/fuse_test.rs +++ b/clients/filesystem-fuse/tests/fuse_test.rs @@ -87,7 +87,7 @@ impl Drop for FuseTest { #[test] fn test_fuse_with_memory_fs() { - tracing_subscriber::fmt().init(); + tracing_subscriber::fmt::init(); panic::set_hook(Box::new(|info| { error!("A panic occurred: {:?}", info);