diff --git a/Cargo.lock b/Cargo.lock index 3e2561b..01338f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,6 +65,17 @@ dependencies = [ "syn", ] +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.3.0" @@ -173,6 +184,19 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +[[package]] +name = "env_logger" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -300,6 +324,15 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "hermit-abi" version = "0.3.9" @@ -340,6 +373,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "hyper" version = "0.14.29" @@ -433,7 +472,9 @@ checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" name = "lws_vfs" version = "0.1.0" dependencies = [ + "env_logger", "libc", + "log", "prost", "serde", "serde_json", @@ -494,7 +535,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", ] @@ -817,6 +858,15 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + [[package]] name = "tokio" version = "1.38.0" @@ -1025,6 +1075,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index b9c97a3..bbda702 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,8 @@ windows = "0.28" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" libc = "0.2" +log = "0.4" +env_logger = "0.8" [build-dependencies] tonic-build = "0.11" diff --git a/src/fs_impl/mod.rs b/src/fs_impl/mod.rs index 6f84646..c55a97f 100755 --- a/src/fs_impl/mod.rs +++ b/src/fs_impl/mod.rs @@ -11,7 +11,7 @@ use std::collections::HashMap; extern crate winapi; use std::os::windows::fs::{MetadataExt}; use std::os::windows::prelude::*; -use winapi::um::winnt::FILE_ATTRIBUTE_READONLY; +use winapi::um::winnt::{FILE_ATTRIBUTE_READONLY, FILE_SHARE_READ, FILE_SHARE_WRITE}; use libc; fn from_metadata(sta: &mut Fstat, metadata: &fs::Metadata) -> Result<(), Box> { @@ -33,11 +33,13 @@ enum FileHandle { DIR(ReadDir) } +type FD = u16; + #[derive(Debug, Default)] struct FileFdMgnt { // key is fd, value is FileHandle - files: HashMap, - curr_fd: u64, + files: HashMap, + curr_fd: FD, } impl FileFdMgnt { @@ -51,6 +53,9 @@ impl FileFdMgnt { let refd = self.curr_fd; loop { self.curr_fd += 1; + if self.curr_fd < 3 { + self.curr_fd = 3; + } match self.files.get(&self.curr_fd) { Some(_) => {} None => { @@ -64,24 +69,24 @@ impl FileFdMgnt { ))); } } - Ok(self.curr_fd) + Ok(self.curr_fd as u64) } pub fn push(&mut self, handle: FileHandle) -> Result> { let fd = self.gen_fd()?; println!("push a fd: {}", fd); - self.files.insert(fd, handle); + self.files.insert(fd as u16, handle); Ok(fd) } pub fn pop(&mut self, fd: u64) -> Option { println!("pop a fd: {}", fd); - self.files.remove(&fd) + self.files.remove(&(fd as u16)) } // pub fn get(&mut self, fd: u64) -> Option<&FileHandle> { // self.files.get(&fd) // } pub fn get_mut(&mut self, fd: u64) -> Option<&mut FileHandle> { println!("get a fd: {}", fd); - self.files.get_mut(&fd) + self.files.get_mut(&(fd as u16)) } } @@ -137,7 +142,7 @@ impl FSImpl { let write = flag == libc::O_WRONLY as u32 || flag == libc::O_RDWR as u32; let f = File::options() .read(read) - .write(write).open(path)?; + .write(write).create(write).open(path)?; let fd = self.file_fds.lock().unwrap().push(FileHandle::FILE(f))?; fi.fh = fd; return Ok(0); @@ -317,10 +322,10 @@ impl FSImpl { let _unused = self.fflush(path, fi); } drop(fh); - Ok(0) } else { - Ok(-1) + fs::remove_file(path)?; } + Ok(0) } pub fn fsetxattr( &self, _path: &String, @@ -398,7 +403,7 @@ impl FSImpl { * Introduced in version 2.5 */ pub fn fcreate(&self, path:&String, mode:u32, fi:&mut FileInfo) -> Result> { - let file = File::options().write(true).access_mode(mode).create(true).open(path)?; + let file = File::options().write(true).share_mode(FILE_SHARE_READ|FILE_SHARE_WRITE).access_mode(mode).create(true).open(path)?; let fd = self.file_fds.lock().unwrap().push(FileHandle::FILE(file))?; fi.fh = fd; Ok(0) diff --git a/src/lib.rs b/src/lib.rs index b5bfbf1..aebce4e 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,6 +11,8 @@ use std::fs::File; use std::io::Read as _; use tonic::{Request, Response, Status}; use std::collections::HashMap; +extern crate log; + mod fs_impl; pub mod lws_vfs { tonic::include_proto!("lws_vfs"); @@ -84,7 +86,7 @@ impl LwsVfsIns { } fn lpath(&self, path: &String) -> String { let mut ret = String::new(); - // println!("try to convert {}", path); + // log::trace!("try to convert {}", path); // /l0e -> w: for (k, v) in &self.config.mount_map { if path.starts_with(v) { @@ -92,7 +94,7 @@ impl LwsVfsIns { break; } } - // println!("path convert ret is {}", ret); + // log::trace!("path convert ret is {}", ret); ret } } @@ -104,7 +106,7 @@ impl LwsVfs for LwsVfsIns { request: Request, ) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let reply = HelloReply { message: format!("Hello {}!", request.name), @@ -114,14 +116,14 @@ impl LwsVfs for LwsVfsIns { } async fn fgetattr(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let mut fstat = Fstat::default(); let mut fi = FileInfo::default(); let ret = match self.fs.fgetattr(path, &mut fstat, &mut fi) { Ok(ret) => ret, Err(e) => { - println!("Error getting file metadata: {:?}", e); + log::error!("Error getting file metadata: {:?}", e); -1 } }; @@ -135,7 +137,7 @@ impl LwsVfs for LwsVfsIns { } async fn fopen(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let mut fi = match request.fi{ Some(fi) => fi, @@ -146,7 +148,7 @@ impl LwsVfs for LwsVfsIns { 0 } Err(e) => { - println!("Error open file[{}]: {:?}", path, e); + log::error!("Error open file[{}]: {:?}", path, e); -1 } }; @@ -159,7 +161,6 @@ impl LwsVfs for LwsVfsIns { } async fn fread(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); let mut fi = match request.fi{ Some(fi) => fi, None => FileInfo::default(), @@ -171,6 +172,7 @@ impl LwsVfs for LwsVfsIns { unsafe { buff.set_len(size); } + log::trace!("Got a request: fread {}, size {} offset {}", path, request.size, offset); match self.fs.fread(path, &mut buff, &mut size, offset, &mut fi) { Ok(ret) => { let reply = Read { @@ -184,7 +186,7 @@ impl LwsVfs for LwsVfsIns { Ok(Response::new(reply)) } Err(e) => { - println!("Error reading file[{}]: {:?}", path, e); + log::error!("Error reading file[{}]: {:?}", path, e); let reply = Read { path: request.path, buff: Vec::new(), @@ -197,6 +199,7 @@ impl LwsVfs for LwsVfsIns { } } } + async fn fwrite(&self, request: Request) -> Result, Status> { let request = request.into_inner(); let mut fi = match request.fi{ @@ -207,16 +210,17 @@ impl LwsVfs for LwsVfsIns { let buff = request.buff; let mut size = request.size as usize; let offset = request.offset as usize; - println!("Got a fwrite request: size {} offset {}", request.size, offset); + log::trace!("Got a request: Write {}, size {} offset {}", path, request.size, offset); let ret = match self.fs.fwrite(path, &buff, &mut size, offset, &mut fi) { Ok(ret) => ret, Err(e) => { - println!("Error fwrite file[{}]: {:?}", path, e); + log::error!("Error fwrite file[{}]: {:?}", path, e); -1 } }; let reply = Write { ret, + path: path.to_string(), size: size as u64, ..Default::default() }; @@ -224,13 +228,13 @@ impl LwsVfs for LwsVfsIns { } async fn faccess(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let mask = request.mask; let ret = match self.fs.faccess(path, mask) { Ok(ret) => ret, Err(e) => { - println!("Error access file[{}]: {:?}", path, e); + log::error!("Error access file[{}]: {:?}", path, e); -1 } }; @@ -244,7 +248,7 @@ impl LwsVfs for LwsVfsIns { async fn fsetxattr(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let name = request.name.as_ref(); let value = request.value; @@ -253,7 +257,7 @@ impl LwsVfs for LwsVfsIns { let ret = match self.fs.fsetxattr(path, name, &value, size, flags) { Ok(ret) => ret, Err(e) => { - println!("Error: setxattr file[{}]: {:?}", path, e); + log::error!("Error: setxattr file[{}]: {:?}", path, e); -1 } }; @@ -265,14 +269,14 @@ impl LwsVfs for LwsVfsIns { } async fn fgetxattr(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let name = request.name.as_ref(); let size = request.size as usize; let ret = match self.fs.fgetxattr(path, name, size) { Ok(ret) => ret, Err(e) => { - println!("Error: getxattr file[{}]: {:?}", path, e); + log::error!("Error: getxattr file[{}]: {:?}", path, e); -1 } }; @@ -285,7 +289,7 @@ impl LwsVfs for LwsVfsIns { async fn freaddir(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let mut fi = match request.fi{ Some(fi) => fi, None => FileInfo::default(), @@ -297,7 +301,7 @@ impl LwsVfs for LwsVfsIns { let ret = match self.fs.freaddir(path, &mut dirs, size, offset, &mut fi) { Ok(ret) => ret, Err(e) => { - println!("Error: readdir file[{}]: {:?}", path, e); + log::error!("Error: readdir file[{}]: {:?}", path, e); -1 } }; @@ -310,13 +314,13 @@ impl LwsVfs for LwsVfsIns { } async fn fmkdir(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let mode = request.mode; let ret = match self.fs.fmkdir(&path, mode) { Ok(ret) => ret, Err(e) => { - println!("Error: mkdir [{}]: {:?}", path, e); + log::error!("Error: mkdir [{}]: {:?}", path, e); -1 } }; @@ -328,13 +332,13 @@ impl LwsVfs for LwsVfsIns { } async fn ftruncate(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let size = request.size as u64; let ret = match self.fs.ftruncate(path, size) { Ok(ret) => ret, Err(e) => { - println!("Error: truncate file[{}]: {:?}", path, e); + log::error!("Error: truncate file[{}]: {:?}", path, e); -1 } }; @@ -347,14 +351,14 @@ impl LwsVfs for LwsVfsIns { async fn futimens(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let a_time = vec![request.ts[0].tv_sec as u64, request.ts[0].tv_nsec as u64]; let m_time = vec![request.ts[1].tv_sec as u64, request.ts[1].tv_nsec as u64]; let ret = match self.fs.futimens(path, &a_time, &m_time) { Ok(ret) => ret, Err(e) => { - println!("Error: futimens file[{}]: {:?}", path, e); + log::error!("Error: futimens file[{}]: {:?}", path, e); -1 } }; @@ -367,14 +371,14 @@ impl LwsVfs for LwsVfsIns { async fn fchown(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let uid = request.uid as u32; let gid = request.gid as u32; let ret = match self.fs.fchown(path, uid, gid) { Ok(ret) => ret, Err(e) => { - println!("Error: chown file[{}]: {:?}", path, e); + log::error!("Error: chown file[{}]: {:?}", path, e); -1 } }; @@ -386,7 +390,7 @@ impl LwsVfs for LwsVfsIns { } async fn frelease(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let mut fi = match request.fi{ Some(fi) => fi, @@ -395,7 +399,7 @@ impl LwsVfs for LwsVfsIns { let ret = match self.fs.frelease(path, &mut fi, request.flush != 0) { Ok(ret) => ret, Err(e) => { - println!("Error: release file[{}]: {:?}", path, e); + log::error!("Error: release file[{}]: {:?}", path, e); -1 } }; @@ -407,12 +411,12 @@ impl LwsVfs for LwsVfsIns { } async fn frmdir(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let ret = match self.fs.frmdir(path) { Ok(ret) => ret, Err(e) => { - println!("Error: rmdir [{}]: {:?}", path, e); + log::error!("Error: rmdir [{}]: {:?}", path, e); -1 } }; @@ -425,7 +429,7 @@ impl LwsVfs for LwsVfsIns { async fn fflush(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let mut fi = match request.fi{ Some(fi) => fi, @@ -434,7 +438,7 @@ impl LwsVfs for LwsVfsIns { let ret = match self.fs.fflush(path, &mut fi) { Ok(ret) => ret, Err(e) => { - println!("Error: flush file[{}]: {:?}", path, e); + log::error!("Error: flush file[{}]: {:?}", path, e); -1 } }; @@ -447,7 +451,7 @@ impl LwsVfs for LwsVfsIns { async fn fcreate(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let mode = request.mode as u32; let mut fi = match request.fi{ @@ -457,12 +461,13 @@ impl LwsVfs for LwsVfsIns { let ret = match self.fs.fcreate(path, mode, &mut fi) { Ok(ret) => ret, Err(e) => { - println!("Error: create file[{}]: {:?}", path, e); + log::error!("Error: create file[{}]: {:?}", path, e); -1 } }; let reply = Create { ret, + fi:Some(fi), ..Create::default() }; Ok(Response::new(reply)) @@ -470,12 +475,12 @@ impl LwsVfs for LwsVfsIns { async fn funlink(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let ret = match self.fs.funlink(path) { Ok(ret) => ret, Err(e) => { - println!("Error: unlink file[{}]: {:?}", path, e); + log::error!("Error: unlink file[{}]: {:?}", path, e); -1 } }; @@ -488,7 +493,7 @@ impl LwsVfs for LwsVfsIns { async fn fopendir(&self,request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let mut fi = match request.fi{ Some(fi) => fi, @@ -497,7 +502,7 @@ impl LwsVfs for LwsVfsIns { let ret = match self.fs.fopendir(path, &mut fi) { Ok(ret) => ret, Err(e) => { - println!("Error: opendir dir[{}]: {:?}", path, e); + log::error!("Error: opendir dir[{}]: {:?}", path, e); -1 } }; @@ -511,7 +516,7 @@ impl LwsVfs for LwsVfsIns { async fn freleasedir(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let path = &self.lpath(&request.path); let mut fi = match request.fi{ Some(fi) => fi, @@ -520,7 +525,7 @@ impl LwsVfs for LwsVfsIns { let ret = match self.fs.freleasedir(path, &mut fi) { Ok(ret) => ret, Err(e) => { - println!("Error: releasedir file[{}]: {:?}", path, e); + log::error!("Error: releasedir file[{}]: {:?}", path, e); -1 } }; @@ -533,13 +538,13 @@ impl LwsVfs for LwsVfsIns { async fn frename(&self, request: Request) -> Result, Status> { let request = request.into_inner(); - println!("Got a request: {:?}", request); + log::trace!("Got a request: {:?}", request); let from = &self.lpath(&request.path); let to = &self.lpath(&request.new); let ret = match self.fs.frename(from, to) { Ok(ret) => ret, Err(e) => { - println!("Error: rename file[{}]: {:?}", from, e); + log::error!("Error: rename file[{}]: {:?}", from, e); -1 } }; diff --git a/src/server.rs b/src/server.rs index 72c66b2..54b8019 100644 --- a/src/server.rs +++ b/src/server.rs @@ -2,7 +2,7 @@ use tonic::transport; use lws_vfs::LwsVfsIns; use lws_vfs::lws_vfs::lws_vfs_server::LwsVfsServer; - +extern crate log; // fn main() { // println!("Hello, world!"); // let file = "test.txt"; @@ -16,15 +16,16 @@ use lws_vfs::lws_vfs::lws_vfs_server::LwsVfsServer; #[tokio::main] async fn main() -> Result<(), Box> { + env_logger::init(); let instance = match LwsVfsIns::new("config.json"){ Ok(greeter) => greeter, Err(e) => { - println!("Error creating lws server instance: {:?}", e); + log::error!("Error creating lws server instance: {:?}", e); return Err(e); } }; let addr = format!("0.0.0.0:{}", instance.config.get_port()); - println!("Listening on {}", addr); + log::info!("Listening on {}", addr); transport::Server::builder() .add_service(LwsVfsServer::new(instance)) .serve(addr.parse()?)