This is an automated email from the ASF dual-hosted git repository.
jshao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new e85e47dcd8 [#6320] feat (gvfs-fuse): Support mount and umount command
for gvfs-fuse command line tools (#6321)
e85e47dcd8 is described below
commit e85e47dcd859008a123f141945cc70546f36f725
Author: Yuhui <[email protected]>
AuthorDate: Fri Feb 7 14:28:20 2025 +0800
[#6320] feat (gvfs-fuse): Support mount and umount command for gvfs-fuse
command line tools (#6321)
### What changes were proposed in this pull request?
1. Support mount and umount command
2. Make mount create a daemon process to run background
### Why are the changes needed?
Fix: #6320
### Does this PR introduce _any_ user-facing change?
No
### How was this patch tested?
IT
---------
Co-authored-by: Qiming Teng <[email protected]>
---
clients/filesystem-fuse/Cargo.toml | 2 +
clients/filesystem-fuse/conf/gvfs_fuse.toml | 1 +
clients/filesystem-fuse/src/command_args.rs | 59 ++++++
clients/filesystem-fuse/src/config.rs | 72 +++++--
clients/filesystem-fuse/src/fuse_server.rs | 3 +-
clients/filesystem-fuse/src/lib.rs | 3 +
clients/filesystem-fuse/src/main.rs | 229 ++++++++++++++++++---
clients/filesystem-fuse/src/s3_filesystem.rs | 2 +-
clients/filesystem-fuse/tests/bin/gvfs_fuse.sh | 9 +-
.../filesystem-fuse/tests/conf/config_test.toml | 2 +
.../filesystem-fuse/tests/conf/gvfs_fuse_s3.toml | 1 +
clients/filesystem-fuse/tests/fuse_test.rs | 2 +-
12 files changed, 328 insertions(+), 57 deletions(-)
diff --git a/clients/filesystem-fuse/Cargo.toml
b/clients/filesystem-fuse/Cargo.toml
index 3760bd5285..e600683689 100644
--- a/clients/filesystem-fuse/Cargo.toml
+++ b/clients/filesystem-fuse/Cargo.toml
@@ -35,7 +35,9 @@ name = "gvfs_fuse"
[dependencies]
async-trait = "0.1"
bytes = "1.6.0"
+clap = { version = "4.5.24", features = ["derive"] }
config = "0.13"
+daemonize = "0.5.0"
dashmap = "6.1.0"
fuse3 = { version = "0.8.1", "features" = ["tokio-runtime", "unprivileged"] }
futures-util = "0.3.30"
diff --git a/clients/filesystem-fuse/conf/gvfs_fuse.toml
b/clients/filesystem-fuse/conf/gvfs_fuse.toml
index 4bde0e9e1b..27e52fc7d5 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"
+data_path = "target/gvfs-fuse"
[fuse.properties]
diff --git a/clients/filesystem-fuse/src/command_args.rs
b/clients/filesystem-fuse/src/command_args.rs
new file mode 100644
index 0000000000..bb442f167d
--- /dev/null
+++ b/clients/filesystem-fuse/src/command_args.rs
@@ -0,0 +1,59 @@
+/*
+ * 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 clap::{Parser, Subcommand};
+
+#[derive(Parser, Debug)]
+#[command(
+ name = "gvfs-fuse",
+ version = "0.1",
+ about = "A FUSE-based file system client"
+)]
+pub(crate) struct Arguments {
+ #[command(subcommand)]
+ pub(crate) command: Commands,
+}
+
+#[derive(Subcommand, Debug)]
+pub(crate) enum Commands {
+ Mount {
+ #[arg(help = "Mount point for the filesystem")]
+ mount_point: String,
+
+ #[arg(
+ help = "The URI of the GVFS fileset, like
gvfs://fileset/my_catalog/my_schema/my_fileset"
+ )]
+ fileset_location: String,
+
+ #[arg(short, long, help = "Path to the configuration file")]
+ config: Option<String>,
+
+ #[arg(short, long, help = "Debug level", default_value_t = 0)]
+ debug: u8,
+
+ #[arg(short, long, default_value_t = false, help = "Run in
foreground")]
+ foreground: bool,
+ },
+ Umount {
+ #[arg(help = "Mount point to umount")]
+ mount_point: String,
+
+ #[arg(short, long, help = "Force umount")]
+ force: bool,
+ },
+}
diff --git a/clients/filesystem-fuse/src/config.rs
b/clients/filesystem-fuse/src/config.rs
index 17908fd08f..890cb7d31d 100644
--- a/clients/filesystem-fuse/src/config.rs
+++ b/clients/filesystem-fuse/src/config.rs
@@ -24,6 +24,7 @@ use serde::Deserialize;
use std::collections::HashMap;
use std::fs;
+// FuseConfig
pub(crate) const CONF_FUSE_FILE_MASK: ConfigEntity<u32> = ConfigEntity::new(
FuseConfig::MODULE_NAME,
"file_mask",
@@ -45,13 +46,28 @@ pub(crate) const CONF_FUSE_FS_TYPE: ConfigEntity<&'static
str> = ConfigEntity::n
"memory",
);
-pub(crate) const CONF_FUSE_CONFIG_PATH: ConfigEntity<&'static str> =
ConfigEntity::new(
+pub(crate) const CONF_FUSE_CONFIG_FILE_PATH: ConfigEntity<&'static str> =
ConfigEntity::new(
FuseConfig::MODULE_NAME,
"config_path",
"The path of the FUSE configuration file",
- "/etc/gvfs/gvfs.toml",
+ "/etc/gvfs-fuse/config.toml",
);
+pub(crate) const CONF_FUSE_DATA_DIR: ConfigEntity<&'static str> =
ConfigEntity::new(
+ FuseConfig::MODULE_NAME,
+ "data_dir",
+ "The data path of GVFS FUSE",
+ "/var/data/gvfs-fuse",
+);
+
+pub(crate) const CONF_FUSE_LOG_DIR: ConfigEntity<&'static str> =
ConfigEntity::new(
+ FuseConfig::MODULE_NAME,
+ "log_dir",
+ "The log path of GVFS FUSE",
+ "logs", //relative to the data path
+);
+
+// FilesystemConfig
pub(crate) const CONF_FILESYSTEM_BLOCK_SIZE: ConfigEntity<u32> =
ConfigEntity::new(
FilesystemConfig::MODULE_NAME,
"block_size",
@@ -59,6 +75,7 @@ pub(crate) const CONF_FILESYSTEM_BLOCK_SIZE:
ConfigEntity<u32> = ConfigEntity::n
4096,
);
+// GravitinoConfig
pub(crate) const CONF_GRAVITINO_URI: ConfigEntity<&'static str> =
ConfigEntity::new(
GravitinoConfig::MODULE_NAME,
"uri",
@@ -125,22 +142,32 @@ impl Default for DefaultConfig {
ConfigValue::String(CONF_FUSE_FS_TYPE),
);
configs.insert(
- Self::compose_key(CONF_FUSE_CONFIG_PATH),
- ConfigValue::String(CONF_FUSE_CONFIG_PATH),
+ Self::compose_key(CONF_FUSE_CONFIG_FILE_PATH),
+ ConfigValue::String(CONF_FUSE_CONFIG_FILE_PATH),
);
configs.insert(
- Self::compose_key(CONF_GRAVITINO_URI),
- ConfigValue::String(CONF_GRAVITINO_URI),
+ Self::compose_key(CONF_FUSE_DATA_DIR),
+ ConfigValue::String(CONF_FUSE_DATA_DIR),
);
configs.insert(
- Self::compose_key(CONF_GRAVITINO_METALAKE),
- ConfigValue::String(CONF_GRAVITINO_METALAKE),
+ Self::compose_key(CONF_FUSE_LOG_DIR),
+ ConfigValue::String(CONF_FUSE_LOG_DIR),
);
+
configs.insert(
Self::compose_key(CONF_FILESYSTEM_BLOCK_SIZE),
ConfigValue::U32(CONF_FILESYSTEM_BLOCK_SIZE),
);
+ configs.insert(
+ Self::compose_key(CONF_GRAVITINO_URI),
+ ConfigValue::String(CONF_GRAVITINO_URI),
+ );
+ configs.insert(
+ Self::compose_key(CONF_GRAVITINO_METALAKE),
+ ConfigValue::String(CONF_GRAVITINO_METALAKE),
+ );
+
DefaultConfig { configs }
}
}
@@ -205,38 +232,39 @@ impl AppConfig {
.unwrap_or_else(|e| panic!("Failed to set default for {}: {}",
entity.name, e))
}
- pub fn from_file(config_file_path: Option<&str>) -> GvfsResult<AppConfig> {
+ pub fn from_file(config_file_path: Option<String>) ->
GvfsResult<AppConfig> {
let builder = Self::crete_default_config_builder();
let config_path = {
if config_file_path.is_some() {
let path = config_file_path.unwrap();
//check config file exists
- if fs::metadata(path).is_err() {
+ if fs::metadata(&path).is_err() {
return Err(
ConfigNotFound.to_error("The configuration file not
found".to_string())
);
}
- info!("Use configuration file: {}", path);
+ info!("Use configuration file: {}", &path);
path
} else {
- //use default config
- if fs::metadata(CONF_FUSE_CONFIG_PATH.default).is_err() {
+ if fs::metadata(CONF_FUSE_CONFIG_FILE_PATH.default).is_err() {
+ //use default config
warn!(
"The default configuration file is not found, using
the default configuration"
);
return Ok(AppConfig::default());
} else {
+ //use the default configuration file
warn!(
"Using the default config file {}",
- CONF_FUSE_CONFIG_PATH.default
+ CONF_FUSE_CONFIG_FILE_PATH.default
);
}
- CONF_FUSE_CONFIG_PATH.default
+ CONF_FUSE_CONFIG_FILE_PATH.default.to_string()
}
};
let config = builder
- .add_source(config::File::with_name(config_path).required(true))
+ .add_source(config::File::with_name(&config_path).required(true))
.build();
if let Err(e) = config {
let msg = format!("Failed to build configuration: {}", e);
@@ -265,7 +293,11 @@ pub struct FuseConfig {
#[serde(default)]
pub fs_type: String,
#[serde(default)]
- pub config_path: String,
+ pub config_file_path: String,
+ #[serde(default)]
+ pub data_dir: String,
+ #[serde(default)]
+ pub log_dir: String,
#[serde(default)]
pub properties: HashMap<String, String>,
}
@@ -302,9 +334,11 @@ mod test {
#[test]
fn test_config_from_file() {
- let config =
AppConfig::from_file(Some("tests/conf/config_test.toml")).unwrap();
+ let config =
AppConfig::from_file(Some("tests/conf/config_test.toml".to_string())).unwrap();
assert_eq!(config.fuse.file_mask, 0o644);
assert_eq!(config.fuse.dir_mask, 0o755);
+ assert_eq!(config.fuse.data_dir, "/target/gvfs-fuse");
+ assert_eq!(config.fuse.log_dir, "/target/gvfs-fuse/logs");
assert_eq!(config.filesystem.block_size, 8192);
assert_eq!(config.gravitino.uri, "http://localhost:8090");
assert_eq!(config.gravitino.metalake, "test");
@@ -323,6 +357,8 @@ mod test {
let config = AppConfig::default();
assert_eq!(config.fuse.file_mask, 0o600);
assert_eq!(config.fuse.dir_mask, 0o700);
+ assert_eq!(config.fuse.data_dir, "/var/data/gvfs-fuse");
+ assert_eq!(config.fuse.log_dir, "logs");
assert_eq!(config.filesystem.block_size, 4096);
assert_eq!(config.gravitino.uri, "http://localhost:8090");
assert_eq!(config.gravitino.metalake, "");
diff --git a/clients/filesystem-fuse/src/fuse_server.rs
b/clients/filesystem-fuse/src/fuse_server.rs
index a059686e16..0e8bd51833 100644
--- a/clients/filesystem-fuse/src/fuse_server.rs
+++ b/clients/filesystem-fuse/src/fuse_server.rs
@@ -20,6 +20,7 @@ use crate::utils::GvfsResult;
use fuse3::raw::{Filesystem, Session};
use fuse3::MountOptions;
use log::{error, info};
+use std::path::Path;
use std::process::exit;
use std::sync::Arc;
use tokio::select;
@@ -46,7 +47,7 @@ impl FuseServer {
/// Starts the FUSE filesystem and blocks until it is stopped.
pub async fn start(&self, fuse_fs: impl Filesystem + Sync + 'static) ->
GvfsResult<()> {
//check if the mount point exists
- if !std::path::Path::new(&self.mount_point).exists() {
+ if !Path::new(&self.mount_point).exists() {
error!("Mount point {} does not exist", self.mount_point);
exit(libc::ENOENT);
}
diff --git a/clients/filesystem-fuse/src/lib.rs
b/clients/filesystem-fuse/src/lib.rs
index 41a9a5335d..65cd878f34 100644
--- a/clients/filesystem-fuse/src/lib.rs
+++ b/clients/filesystem-fuse/src/lib.rs
@@ -49,6 +49,9 @@ macro_rules! test_enable_with {
pub const RUN_TEST_WITH_S3: &str = "RUN_TEST_WITH_S3";
pub const RUN_TEST_WITH_FUSE: &str = "RUN_TEST_WITH_FUSE";
+pub const LOG_FILE_NAME: &str = "gvfs-fuse.log";
+pub const PID_FILE_NAME: &str = "gvfs-fuse.pid";
+
pub async fn gvfs_mount(mount_to: &str, mount_from: &str, config: &AppConfig)
-> GvfsResult<()> {
gvfs_fuse::mount(mount_to, mount_from, config).await
}
diff --git a/clients/filesystem-fuse/src/main.rs
b/clients/filesystem-fuse/src/main.rs
index 4e517c76b3..6c8c0f4e0e 100644
--- a/clients/filesystem-fuse/src/main.rs
+++ b/clients/filesystem-fuse/src/main.rs
@@ -16,49 +16,214 @@
* specific language governing permissions and limitations
* under the License.
*/
-use fuse3::Errno;
+mod command_args;
+
+use crate::command_args::Commands;
+use clap::Parser;
+use daemonize::Daemonize;
use gvfs_fuse::config::AppConfig;
-use gvfs_fuse::{gvfs_mount, gvfs_unmount};
+use gvfs_fuse::{gvfs_mount, gvfs_unmount, LOG_FILE_NAME, PID_FILE_NAME};
use log::{error, info};
+use std::fs::{create_dir, OpenOptions};
+use std::io;
+use std::path::Path;
+use std::process::Command;
+use tokio::runtime::Runtime;
use tokio::signal;
+use tokio::signal::unix::{signal, SignalKind};
-#[tokio::main]
-async fn main() -> fuse3::Result<()> {
- tracing_subscriber::fmt::init();
-
- // todo need inmprove the args parsing
- let args: Vec<String> = std::env::args().collect();
- let (mount_point, mount_from, config_path) = match args.len() {
- 4 => (args[1].clone(), args[2].clone(), args[3].clone()),
- _ => {
- error!("Usage: {} <mount_point> <mount_from> <config>", args[0]);
- return Err(Errno::from(libc::EINVAL));
- }
+fn init_work_dirs(config: &AppConfig, mount_point: &str) -> io::Result<()> {
+ let data_dir_name = Path::new(&config.fuse.data_dir).to_path_buf();
+ let data_dir_name = data_dir_name.canonicalize()?;
+ if !data_dir_name.exists() {
+ Err(io::Error::new(
+ io::ErrorKind::NotFound,
+ format!("Data directory {} not found", &config.fuse.data_dir),
+ ))?
+ };
+
+ let mount_point_name = data_dir_name.join(mount_point);
+ if !mount_point_name.exists() {
+ create_dir(&mount_point_name)?
+ };
+
+ let log_dir_name = data_dir_name.join(&config.fuse.log_dir);
+ if !log_dir_name.exists() {
+ create_dir(&log_dir_name)?
};
- //todo(read config file from args)
- let config = AppConfig::from_file(Some(&config_path));
- if let Err(e) = &config {
- error!("Failed to load config: {:?}", e);
- return Err(Errno::from(libc::EINVAL));
+ Ok(())
+}
+
+fn make_daemon(config: &AppConfig) -> io::Result<()> {
+ let data_dir_name = Path::new(&config.fuse.data_dir);
+ let log_dir_name = data_dir_name.join(&config.fuse.log_dir);
+ let log_file_name = log_dir_name.join(LOG_FILE_NAME);
+ let log_file = OpenOptions::new()
+ .create(true)
+ .append(true)
+ .open(&log_file_name)
+ .unwrap();
+ let log_err_file =
OpenOptions::new().append(true).open(log_file_name).unwrap();
+
+ let pid_file_name = data_dir_name.join(PID_FILE_NAME);
+
+ let daemonize = Daemonize::new()
+ .pid_file(pid_file_name)
+ .chown_pid_file(true)
+ .working_directory(data_dir_name)
+ .stdout(log_file)
+ .stderr(log_err_file);
+
+ match daemonize.start() {
+ Ok(_) => info!("Gvfs-fuse Daemon started successfully"),
+ Err(e) => {
+ return Err(io::Error::new(
+ io::ErrorKind::Other,
+ format!("Gvfs-fuse Daemon failed to start: {:?}", e),
+ ))
+ }
}
- let config = config.unwrap();
- let handle = tokio::spawn(async move {
- let result = gvfs_mount(&mount_point, &mount_from, &config).await;
- if let Err(e) = result {
- error!("Failed to mount gvfs: {:?}", e);
- return Err(Errno::from(libc::EINVAL));
+ Ok(())
+}
+
+fn mount_fuse(config: AppConfig, mount_point: String, target: String) ->
io::Result<()> {
+ let rt = Runtime::new()?;
+ rt.block_on(async {
+ let handle = tokio::spawn(async move {
+ let result = gvfs_mount(&mount_point, &target, &config).await;
+ if let Err(e) = result {
+ error!("Failed to mount gvfs: {:?}", e);
+ return Err(io::Error::from(io::ErrorKind::InvalidInput));
+ }
+ Ok(())
+ });
+
+ let mut term_signal = signal(SignalKind::terminate())?;
+ tokio::select! {
+ _ = handle => {}
+ _ = signal::ctrl_c() => {
+ info!("Received Ctrl+C, unmounting gvfs...")
+ }
+ _ = term_signal.recv()=> {
+ info!("Received SIGTERM, unmounting gvfs...")
+ }
}
+
+ let _ = gvfs_unmount().await;
Ok(())
- });
+ })
+}
- tokio::select! {
- _ = handle => {}
- _ = signal::ctrl_c() => {
- info!("Received Ctrl+C, unmounting gvfs...");
+#[cfg(target_os = "macos")]
+fn do_umount(mp: &str, force: bool) -> std::io::Result<()> {
+ let cmd_result = if force {
+ Command::new("umount").arg("-f").arg(mp).output()
+ } else {
+ Command::new("umount").arg(mp).output()
+ };
+
+ handle_command_result(cmd_result)
+}
+
+#[cfg(target_os = "linux")]
+fn do_umount(mp: &str, force: bool) -> std::io::Result<()> {
+ let cmd_result =
+ if Path::new("/bin/fusermount").exists() ||
Path::new("/usr/bin/fusermount").exists() {
+ if force {
+ Command::new("fusermount").arg("-uz").arg(mp).output()
+ } else {
+ Command::new("fusermount").arg("-u").arg(mp).output()
+ }
+ } else if force {
+ Command::new("umount").arg("-l").arg(mp).output()
+ } else {
+ Command::new("umount").arg(mp).output()
+ };
+
+ handle_command_result(cmd_result)
+}
+
+fn handle_command_result(cmd_result: io::Result<std::process::Output>) ->
io::Result<()> {
+ match cmd_result {
+ Ok(output) => {
+ if !output.status.success() {
+ let stderr = String::from_utf8_lossy(&output.stderr);
+ Err(io::Error::new(io::ErrorKind::Other, stderr.to_string()))
+ } else {
+ Ok(())
+ }
}
+ Err(e) => Err(e),
}
+}
- let _ = gvfs_unmount().await;
- Ok(())
+#[cfg(not(any(target_os = "macos", target_os = "linux")))]
+fn do_umount(_mp: &str, _force: bool) -> std::io::Result<()> {
+ Err(std::io::Error::new(
+ std::io::ErrorKind::Other,
+ format!("OS {} is not supported", env::consts::OS),
+ ))
+}
+
+fn main() -> Result<(), i32> {
+ tracing_subscriber::fmt().init();
+ let args = command_args::Arguments::parse();
+ match args.command {
+ Commands::Mount {
+ mount_point,
+ fileset_location,
+ config,
+ debug: _,
+ foreground,
+ } => {
+ let app_config = AppConfig::from_file(config);
+ if let Err(e) = &app_config {
+ error!("Failed to load config: {:?}", e);
+ return Err(-1);
+ };
+ let app_config = app_config.unwrap();
+
+ let mount_point = {
+ let path = Path::new(&mount_point).canonicalize();
+ if let Err(e) = path {
+ error!("Failed to resolve mount point: {:?}", e);
+ return Err(-1);
+ };
+ let path = path.unwrap();
+ path.to_string_lossy().to_string()
+ };
+
+ let result = init_work_dirs(&app_config, &mount_point);
+ if let Err(e) = result {
+ error!("Failed to initialize working directories: {:?}", e);
+ return Err(-1);
+ }
+
+ let result = if foreground {
+ mount_fuse(app_config, mount_point, fileset_location)
+ } else {
+ let result = make_daemon(&app_config);
+ if let Err(e) = result {
+ error!("Failed to daemonize: {:?}", e);
+ return Err(-1);
+ };
+ mount_fuse(app_config, mount_point, fileset_location)
+ };
+
+ if let Err(e) = result {
+ error!("Failed to mount gvfs: {:?}", e.to_string());
+ return Err(-1);
+ };
+ Ok(())
+ }
+ Commands::Umount { mount_point, force } => {
+ let result = do_umount(&mount_point, force);
+ if let Err(e) = result {
+ error!("Failed to unmount gvfs: {:?}", e.to_string());
+ return Err(-1);
+ };
+ Ok(())
+ }
+ }
}
diff --git a/clients/filesystem-fuse/src/s3_filesystem.rs
b/clients/filesystem-fuse/src/s3_filesystem.rs
index 35a091b3fe..e397d31ccf 100644
--- a/clients/filesystem-fuse/src/s3_filesystem.rs
+++ b/clients/filesystem-fuse/src/s3_filesystem.rs
@@ -255,7 +255,7 @@ pub(crate) mod tests {
config_file_name = source_file_name;
}
- AppConfig::from_file(Some(config_file_name)).unwrap()
+ AppConfig::from_file(Some(config_file_name.to_string())).unwrap()
}
#[tokio::test]
diff --git a/clients/filesystem-fuse/tests/bin/gvfs_fuse.sh
b/clients/filesystem-fuse/tests/bin/gvfs_fuse.sh
index e706d8e2c0..3089a9a1a1 100644
--- a/clients/filesystem-fuse/tests/bin/gvfs_fuse.sh
+++ b/clients/filesystem-fuse/tests/bin/gvfs_fuse.sh
@@ -52,14 +52,15 @@ start_gvfs_fuse() {
make build
echo "Starting gvfs-fuse-daemon"
- $CLIENT_FUSE_DIR/target/debug/gvfs-fuse $MOUNT_DIR $MOUNT_FROM_LOCATION
$TEST_CONFIG_FILE > \
+ mkdir -p target/debug/gvfs-dir
+ $CLIENT_FUSE_DIR/target/debug/gvfs-fuse mount $MOUNT_DIR
$MOUNT_FROM_LOCATION -c $TEST_CONFIG_FILE -f > \
$CLIENT_FUSE_DIR/target/debug/fuse.log 2>&1 &
check_gvfs_fuse_ready
cd -
}
stop_gvfs_fuse() {
- # Stop the gvfs-fuse process if it's running
- pkill -INT gvfs-fuse || true
+ # Unmount the gvfs-fuse
+ $CLIENT_FUSE_DIR/target/debug/gvfs-fuse umount $MOUNT_DIR
echo "Stopping gvfs-fuse-daemon"
-}
\ No newline at end of file
+}
diff --git a/clients/filesystem-fuse/tests/conf/config_test.toml
b/clients/filesystem-fuse/tests/conf/config_test.toml
index 524e0aa94f..e7cbf02c7f 100644
--- a/clients/filesystem-fuse/tests/conf/config_test.toml
+++ b/clients/filesystem-fuse/tests/conf/config_test.toml
@@ -20,6 +20,8 @@
file_mask= 0o644
dir_mask= 0o755
fs_type = "memory"
+data_dir = "/target/gvfs-fuse"
+log_dir = "/target/gvfs-fuse/logs"
[fuse.properties]
key1 = "value1"
diff --git a/clients/filesystem-fuse/tests/conf/gvfs_fuse_s3.toml
b/clients/filesystem-fuse/tests/conf/gvfs_fuse_s3.toml
index d0ff8e5dde..69a3fcaf36 100644
--- a/clients/filesystem-fuse/tests/conf/gvfs_fuse_s3.toml
+++ b/clients/filesystem-fuse/tests/conf/gvfs_fuse_s3.toml
@@ -20,6 +20,7 @@
file_mask= 0o600
dir_mask= 0o700
fs_type = "gvfs"
+data_dir = "target/debug/gvfs-dir"
[fuse.properties]
key1 = "value1"
diff --git a/clients/filesystem-fuse/tests/fuse_test.rs
b/clients/filesystem-fuse/tests/fuse_test.rs
index 1d1ef80b78..cd7dbf7ea9 100644
--- a/clients/filesystem-fuse/tests/fuse_test.rs
+++ b/clients/filesystem-fuse/tests/fuse_test.rs
@@ -45,7 +45,7 @@ impl FuseTestEnv {
info!("Start gvfs fuse server");
let mount_point = self.mount_point.clone();
- let config =
AppConfig::from_file(Some("tests/conf/gvfs_fuse_memory.toml"))
+ let config =
AppConfig::from_file(Some("tests/conf/gvfs_fuse_memory.toml".to_string()))
.expect("Failed to load config");
ASYNC_RUNTIME.spawn(async move {
let result = gvfs_mount(&mount_point, "", &config).await;