Compare commits
No commits in common. "fa5b137db159d83e410ea9c79779acfcad6b5861" and "b60feeb7ed9d9e8da7c25059d076f48410c8216f" have entirely different histories.
fa5b137db1
...
b60feeb7ed
|
@ -19,8 +19,6 @@ hashbrown = "0.9.0"
|
|||
log = "0.4"
|
||||
env_logger = "0.8"
|
||||
clap = "3.0"
|
||||
nix = { version = "0.29.0", features = ["process", "feature"]}
|
||||
signal-hook = "0.3.17"
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build = "0.11"
|
||||
|
|
|
@ -1,10 +1,3 @@
|
|||
# lws_client
|
||||
|
||||
lws的客户端。运行在linux服务器上。使用fuser
|
||||
|
||||
|
||||
如果要编译libfue3.0 的版本
|
||||
需要将如下的命令撤销,还原回来原来的路径,将优先链接libfuse3
|
||||
```bash
|
||||
mv /usr/local/lib/x86_64-linux-gnu/ /usr/local/lib/x86_64-linux-gnu_fuse3
|
||||
```
|
||||
lws的客户端。运行在linux服务器上。使用fuser
|
105
src/client.rs
105
src/client.rs
|
@ -1,15 +1,49 @@
|
|||
use clap::{App, Arg};
|
||||
use lws_client::LwsVfsIns;
|
||||
use std::{process, thread};
|
||||
use std::process::Command;
|
||||
use std::thread;
|
||||
extern crate log;
|
||||
use nix::unistd::{fork, ForkResult, getpid, getppid};
|
||||
use signal_hook::consts::{SIGCHLD, SIGINT};
|
||||
use signal_hook::iterator::Signals;
|
||||
|
||||
use std::env;
|
||||
|
||||
const DEFAULT_PORT: u16 = 33444;
|
||||
const DEFAULT_CACHE_LIFE: u32 = 10_000;
|
||||
// use std::process::{Command,Stdio};
|
||||
// fn get_ssh_clinet() -> String {
|
||||
// // Run `who` command
|
||||
// let who = Command::new("who")
|
||||
// .stdout(Stdio::piped())
|
||||
// .spawn().unwrap();
|
||||
|
||||
// // Run `grep $(whoami)` command
|
||||
// let whoami = Command::new("whoami")
|
||||
// .stdout(Stdio::piped())
|
||||
// .output().unwrap();
|
||||
// let user = String::from_utf8_lossy(&whoami.stdout).trim().to_string();
|
||||
|
||||
// let grep = Command::new("grep")
|
||||
// .arg(&user)
|
||||
// .stdin(Stdio::from(who.stdout.unwrap()))
|
||||
// .stdout(Stdio::piped())
|
||||
// .spawn().unwrap();
|
||||
|
||||
// // Run `awk '{print $5}'` command
|
||||
// let awk = Command::new("awk")
|
||||
// .arg("{print $5}")
|
||||
// .stdin(Stdio::from(grep.stdout.unwrap()))
|
||||
// .stdout(Stdio::piped())
|
||||
// .spawn().unwrap();
|
||||
|
||||
// // Collect the output
|
||||
// let output = awk.wait_with_output().unwrap();
|
||||
// let output = String::from_utf8_lossy(&output.stdout).to_string();
|
||||
// println!("output: {}",output);
|
||||
// let mut iter = output.split("(");
|
||||
// iter.next();
|
||||
// let output = iter.next().unwrap().split(")").collect::<Vec<&str>>()[0].to_string();
|
||||
// println!("output: {}",output);
|
||||
// output
|
||||
// }
|
||||
|
||||
fn get_ssh_clinet() -> String {
|
||||
// 获取特定环境变量的值
|
||||
let client = env::var("SSH_CLIENT").expect("only support auto get ssh connection");
|
||||
|
@ -89,43 +123,6 @@ fn param_parser() -> (String, String, u32) {
|
|||
(server, mount_point, cache_life)
|
||||
}
|
||||
|
||||
fn umount_point(mount: &String) {
|
||||
log::info!("fusermount -u {}", mount);
|
||||
let output = Command::new("fusermount")
|
||||
.arg("-u")
|
||||
.arg(mount)
|
||||
.output()
|
||||
.expect("umount command execaute failed");
|
||||
if output.status.success(){
|
||||
log::info!("{}", format!("umount {} success", mount));
|
||||
} else {
|
||||
if let Some(code) = output.status.code() {
|
||||
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
|
||||
let stderr:String = String::from_utf8_lossy(&output.stderr).to_string();
|
||||
// 不存在的话就不需要umount了
|
||||
if stderr.contains("not found") {
|
||||
log::info!("{}", format!("not need umount {}", mount));
|
||||
return;
|
||||
}
|
||||
log::error!("{}", format!("umount {} fail: {}", mount, code));
|
||||
log::error!("{} {}", stdout, stderr);
|
||||
} else {
|
||||
log::error!("{}", format!("umount {} interrupted", mount));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
fn set_cleanup(mount: &String) {
|
||||
// 捕获 SIGCHLD 信号
|
||||
log::info!("waiting for SIGCHLD SIGINT signal");
|
||||
let mut signals = Signals::new(&[SIGCHLD, SIGINT]).expect("Error creating signals");
|
||||
for _ in signals.forever() {
|
||||
log::info!("Catch SIGCHLD||SIGINT, exit....");
|
||||
umount_point(&mount);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
env_logger::init();
|
||||
|
@ -137,9 +134,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
return Err(e);
|
||||
}
|
||||
};
|
||||
// 尝试卸载此前的挂载点
|
||||
umount_point(&mount_point);
|
||||
child_process(&mount_point);
|
||||
log::info!("lws client instance created");
|
||||
match lws_ins.hello().await {
|
||||
Err(e) => {
|
||||
|
@ -166,25 +160,4 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||
)))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fn child_process(mount: &String) {
|
||||
match unsafe{fork()} {
|
||||
Ok(ForkResult::Parent { child: _ }) => {
|
||||
// no thing
|
||||
}
|
||||
Ok(ForkResult::Child) => {
|
||||
let pid = getpid();
|
||||
let ppid = getppid();
|
||||
log::info!("parent: {}, child: {}", ppid, pid);
|
||||
set_cleanup(mount);
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!("fork fail: {}", err);
|
||||
process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
114
src/lib.rs
114
src/lib.rs
|
@ -7,9 +7,10 @@ use lws_client::{
|
|||
use serde_json::{self, Value};
|
||||
use std::error::Error;
|
||||
use std::ffi::OsStr;
|
||||
use std::io::{Error as IoError, ErrorKind};
|
||||
use std::thread::{self};
|
||||
use std::{env, vec};
|
||||
use std::fs::File;
|
||||
use std::io::{Error as IoError, ErrorKind, Read as IoRead};
|
||||
use std::thread::{self, JoinHandle};
|
||||
use std::{env, path, vec};
|
||||
use tokio::runtime::{Builder, Runtime};
|
||||
use tonic::transport::Channel as RpcChannel;
|
||||
extern crate log;
|
||||
|
@ -237,12 +238,12 @@ impl VirFs {
|
|||
//self.match_path(&mut vname)
|
||||
}
|
||||
|
||||
pub fn _match_path<'a>(&self, name_list: &mut impl Iterator<Item = &'a str>) -> Option<&VirFs> {
|
||||
pub fn match_path<'a>(&self, name_list: &mut impl Iterator<Item = &'a str>) -> Option<&VirFs> {
|
||||
if let Some(current) = name_list.next() {
|
||||
match self.sub.get(current) {
|
||||
Some(v) => {
|
||||
// try match sub dir
|
||||
if let Some(sub) = v._match_path(name_list) {
|
||||
if let Some(sub) = v.match_path(name_list) {
|
||||
Some(sub)
|
||||
// sub dirs not match
|
||||
} else {
|
||||
|
@ -312,7 +313,7 @@ impl FileAttrCacheCtx {
|
|||
}
|
||||
|
||||
pub struct FileAttrCacheManager {
|
||||
_handle: thread::JoinHandle<()>,
|
||||
handle: thread::JoinHandle<()>,
|
||||
tx: mpsc::Sender<FileAttrCacheMsg>,
|
||||
}
|
||||
|
||||
|
@ -323,7 +324,7 @@ impl FileAttrCacheManager {
|
|||
let handle = thread::spawn(move || {
|
||||
Self::cache_manager(cache_ctx, cache_life);
|
||||
});
|
||||
FileAttrCacheManager { _handle:handle, tx }
|
||||
FileAttrCacheManager { handle, tx }
|
||||
}
|
||||
|
||||
fn cache_manager(mut ctx: FileAttrCacheCtx, cache_life: u32) {
|
||||
|
@ -431,16 +432,6 @@ pub struct LwsVfsIns {
|
|||
cache: FileAttrCacheManager,
|
||||
}
|
||||
|
||||
/// 将返回值转换为 Result<(), i32> 类型,给rpc使用
|
||||
macro_rules! ret2result {
|
||||
($ret:expr) => {
|
||||
match $ret {
|
||||
0 => Ok(()),
|
||||
_ => Err($ret),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn mode_to_filetype(mode: libc::mode_t) -> FileType {
|
||||
match mode & libc::S_IFMT {
|
||||
libc::S_IFDIR => FileType::Directory,
|
||||
|
@ -550,8 +541,8 @@ impl FilesystemMT for LwsVfsIns {
|
|||
};
|
||||
log::trace!("get resp: {:?}", resp);
|
||||
if resp.ret != 0 {
|
||||
self.cache.set(&path, Err(resp.ret));
|
||||
return Err(resp.ret);
|
||||
self.cache.set(&path, Err(libc::ENOENT));
|
||||
return Err(libc::ENOENT);
|
||||
}
|
||||
let attr = file_attr(&resp.stat.unwrap(), &req);
|
||||
self.cache.set(&path, Ok(attr.clone()));
|
||||
|
@ -615,7 +606,10 @@ impl FilesystemMT for LwsVfsIns {
|
|||
}
|
||||
};
|
||||
log::trace!("get resp: {:?}", resp);
|
||||
ret2result!(resp.ret)
|
||||
if resp.ret != 0 {
|
||||
return Err(libc::ENOMSG);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set timestamps of a filesystem entry.
|
||||
|
@ -672,7 +666,10 @@ impl FilesystemMT for LwsVfsIns {
|
|||
}
|
||||
};
|
||||
log::trace!("get resp: {:?}", resp);
|
||||
ret2result!(resp.ret)
|
||||
if resp.ret != 0 {
|
||||
return Err(libc::ENOMSG);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// END OF SETATTR FUNCTIONS
|
||||
|
@ -735,7 +732,7 @@ impl FilesystemMT for LwsVfsIns {
|
|||
};
|
||||
log::trace!("get resp: {:?}", resp);
|
||||
if resp.ret != 0 {
|
||||
return Err(resp.ret)
|
||||
return Err(libc::ENOMSG);
|
||||
}
|
||||
self.getattr(req, Path::new(&path), None)
|
||||
}
|
||||
|
@ -771,7 +768,10 @@ impl FilesystemMT for LwsVfsIns {
|
|||
};
|
||||
self.cache.clr(vec![path]);
|
||||
log::trace!("get resp: {:?}", resp);
|
||||
ret2result!(resp.ret)
|
||||
if resp.ret != 0 {
|
||||
return Err(libc::ENOMSG);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Remove a directory.
|
||||
|
@ -807,7 +807,10 @@ impl FilesystemMT for LwsVfsIns {
|
|||
}
|
||||
};
|
||||
log::trace!("get resp: {:?}", resp);
|
||||
ret2result!(resp.ret)
|
||||
if resp.ret != 0 {
|
||||
return Err(libc::ENOMSG);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Create a symbolic link.
|
||||
|
@ -867,7 +870,10 @@ impl FilesystemMT for LwsVfsIns {
|
|||
}
|
||||
};
|
||||
log::trace!("get resp: {:?}", resp);
|
||||
ret2result!(resp.ret)
|
||||
if resp.ret != 0 {
|
||||
return Err(libc::ENOMSG);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Create a hard link.
|
||||
|
@ -923,7 +929,7 @@ impl FilesystemMT for LwsVfsIns {
|
|||
};
|
||||
log::trace!("get resp: {:?}", resp);
|
||||
if resp.ret != 0 {
|
||||
return Err(resp.ret)
|
||||
return Err(libc::ENOMSG);
|
||||
}
|
||||
let fi = resp.fi.unwrap();
|
||||
Ok((fi.fh, fi.flags))
|
||||
|
@ -983,7 +989,7 @@ impl FilesystemMT for LwsVfsIns {
|
|||
};
|
||||
log::trace!("get fread resp size is: {}", resp.size);
|
||||
if resp.ret != 0 {
|
||||
return callback(Err(resp.ret));
|
||||
return callback(Err(libc::ENOMSG));
|
||||
}
|
||||
callback(Ok(&resp.buff))
|
||||
}
|
||||
|
@ -1038,7 +1044,7 @@ impl FilesystemMT for LwsVfsIns {
|
|||
};
|
||||
log::trace!("get resp: {:?}", resp);
|
||||
if resp.ret != 0 {
|
||||
return Err(resp.ret)
|
||||
return Err(libc::ENOMSG);
|
||||
}
|
||||
Ok(resp.size as u32)
|
||||
}
|
||||
|
@ -1083,7 +1089,10 @@ impl FilesystemMT for LwsVfsIns {
|
|||
}
|
||||
};
|
||||
log::trace!("get resp: {:?}", resp);
|
||||
ret2result!(resp.ret)
|
||||
if resp.ret != 0 {
|
||||
return Err(libc::ENOMSG);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Called when an open file is closed.
|
||||
|
@ -1136,8 +1145,11 @@ impl FilesystemMT for LwsVfsIns {
|
|||
}
|
||||
};
|
||||
log::trace!("get resp: {:?}", resp);
|
||||
ret2result!(resp.ret)
|
||||
if resp.ret != 0 {
|
||||
return Err(libc::ENOMSG);
|
||||
}
|
||||
// self.cache.clr(vec![path]);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write out any pending changes of a file.
|
||||
|
@ -1191,7 +1203,7 @@ impl FilesystemMT for LwsVfsIns {
|
|||
};
|
||||
log::trace!("get resp: {:?}", resp);
|
||||
if resp.ret != 0 {
|
||||
return Err(resp.ret);
|
||||
return Err(libc::ENOMSG);
|
||||
}
|
||||
Ok((resp.fi.unwrap().fh, flags))
|
||||
}
|
||||
|
@ -1256,7 +1268,7 @@ impl FilesystemMT for LwsVfsIns {
|
|||
};
|
||||
log::trace!("get resp: {:?}", resp);
|
||||
if resp.ret != 0 {
|
||||
return Err(resp.ret)
|
||||
return Err(libc::ENOMSG);
|
||||
}
|
||||
let mut dirs = vec![];
|
||||
// let clrs: Vec<String> = resp.dirs.iter().map(|dir| dir.name.clone().into()).collect();
|
||||
|
@ -1309,7 +1321,10 @@ impl FilesystemMT for LwsVfsIns {
|
|||
}
|
||||
};
|
||||
log::trace!("get resp: {:?}", resp);
|
||||
ret2result!(resp.ret)
|
||||
if resp.ret != 0 {
|
||||
return Err(libc::ENOMSG);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write out any pending changes to a directory.
|
||||
|
@ -1429,7 +1444,10 @@ impl FilesystemMT for LwsVfsIns {
|
|||
}
|
||||
};
|
||||
log::trace!("get resp: {:?}", resp);
|
||||
ret2result!(resp.ret)
|
||||
if resp.ret != 0 {
|
||||
return Err(libc::EACCES);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Create and open a new file.
|
||||
|
@ -1483,17 +1501,15 @@ impl FilesystemMT for LwsVfsIns {
|
|||
}
|
||||
self.cache.clr(vec![path.to_string()]);
|
||||
let fi = resp.fi.unwrap();
|
||||
match self.getattr(req, Path::new(&path), Some(fi.fh)) {
|
||||
Ok((ttl, attr)) => {
|
||||
Ok(CreatedEntry {
|
||||
fh: fi.fh,
|
||||
flags,
|
||||
attr,
|
||||
ttl,
|
||||
})
|
||||
},
|
||||
Err(e) => Err(e),
|
||||
if let Ok((ttl, attr)) = self.getattr(req, Path::new(&path), Some(fi.fh)) {
|
||||
return Ok(CreatedEntry {
|
||||
fh: fi.fh,
|
||||
flags,
|
||||
attr,
|
||||
ttl,
|
||||
});
|
||||
}
|
||||
Err(libc::ENOMSG)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1578,15 +1594,7 @@ impl LwsVfsIns {
|
|||
where
|
||||
F: FilesystemMT + Sync + Send + 'static,
|
||||
{
|
||||
let user = match env::var("USER") {
|
||||
Ok(user) => user,
|
||||
Err(_) => {
|
||||
log::warn!("Can not get user name, use 'unknown'");
|
||||
"unknown".to_string()
|
||||
},
|
||||
};
|
||||
let name = format!("fsname=lws_vfs@{}", user);
|
||||
let fuse_args = [OsStr::new("-o"), OsStr::new(name.as_str())];
|
||||
let fuse_args = [OsStr::new("-o"), OsStr::new("fsname=lws_vfs")];
|
||||
fuse_mt::mount(
|
||||
fuse_mt::FuseMT::new(file_system, 10),
|
||||
&mount_point,
|
||||
|
|
Loading…
Reference in New Issue
Block a user