添加初始提交
1. 编译已经通过 2. 添加好了rpc客户端的基本实现 3. 添加好了fuser的架子,内容等待实现
This commit is contained in:
parent
71505636ec
commit
24573524a6
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/target
|
1233
Cargo.lock
generated
Executable file
1233
Cargo.lock
generated
Executable file
File diff suppressed because it is too large
Load Diff
19
Cargo.toml
Normal file
19
Cargo.toml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
[package]
|
||||||
|
name = "lws_client"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[[bin]] # Bin to run the HelloWorld gRPC client
|
||||||
|
name = "lws-client"
|
||||||
|
path = "src/client.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tonic = "0.11"
|
||||||
|
prost = "0.12"
|
||||||
|
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
fuser = "0.14.0"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
tonic-build = "0.11"
|
4
build.rs
Executable file
4
build.rs
Executable file
|
@ -0,0 +1,4 @@
|
||||||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
tonic_build::compile_protos("proto/lws.proto")?;
|
||||||
|
Ok(())
|
||||||
|
}
|
211
proto/lws.proto
Normal file
211
proto/lws.proto
Normal file
|
@ -0,0 +1,211 @@
|
||||||
|
// Copyright 2015 gRPC authors.
|
||||||
|
//
|
||||||
|
// Licensed 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.
|
||||||
|
|
||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package lws_vfs;
|
||||||
|
|
||||||
|
service LwsVfs {
|
||||||
|
// Sends a greeting
|
||||||
|
rpc SayHello(HelloRequest) returns (HelloReply) {}
|
||||||
|
|
||||||
|
rpc fgetattr(getattr) returns (getattr) {}
|
||||||
|
rpc fsetxattr(setxattr) returns (setxattr) {}
|
||||||
|
rpc faccess(access) returns (access) {}
|
||||||
|
rpc freaddir(readdir) returns (readdir) {}
|
||||||
|
rpc fread(read) returns (read) {}
|
||||||
|
rpc fopen(open) returns (open) {}
|
||||||
|
rpc fwrite(write) returns (write) {}
|
||||||
|
rpc fgetxattr(getxattr) returns (getxattr) {}
|
||||||
|
rpc ftruncate(truncate) returns (truncate) {}
|
||||||
|
rpc futimens(utimens) returns (utimens) {}
|
||||||
|
rpc fchown(chown) returns (chown) {}
|
||||||
|
rpc frelease(release) returns (release) {}
|
||||||
|
rpc fmkdir(mkdir) returns (mkdir) {}
|
||||||
|
rpc frmdir(rmdir) returns (rmdir) {}
|
||||||
|
rpc fflush(flush) returns (flush) {}
|
||||||
|
rpc fopendir(opendir) returns (opendir) {}
|
||||||
|
rpc freleasedir(releasedir) returns (releasedir) {}
|
||||||
|
rpc fcreate(create) returns (create) {}
|
||||||
|
rpc funlink(unlink) returns (unlink) {}
|
||||||
|
rpc frename(rename) returns (rename) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The request message containing the user's name.
|
||||||
|
message HelloRequest { string name = 1; }
|
||||||
|
|
||||||
|
// The response message containing the greetings
|
||||||
|
message HelloReply { string message = 1; }
|
||||||
|
|
||||||
|
message file_info {
|
||||||
|
int32 flags = 1;
|
||||||
|
uint32 fh_old = 2;
|
||||||
|
bool direct_io = 3;
|
||||||
|
uint64 fh = 10;
|
||||||
|
uint64 lock_owner = 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
message fstat {
|
||||||
|
uint64 fst_mode = 1;
|
||||||
|
uint64 fst_ino = 2;
|
||||||
|
uint64 fst_dev = 3;
|
||||||
|
uint64 fst_rdev = 4;
|
||||||
|
uint64 fst_nlink = 5;
|
||||||
|
uint64 fst_uid = 6;
|
||||||
|
uint64 fst_gid = 7;
|
||||||
|
uint64 fst_size = 8;
|
||||||
|
uint64 fst_atime = 9;
|
||||||
|
uint64 fst_mtime = 10;
|
||||||
|
uint64 fst_ctime = 11;
|
||||||
|
uint64 fst_blksize = 12;
|
||||||
|
uint64 fst_blocks = 13;
|
||||||
|
}
|
||||||
|
|
||||||
|
// fuse api function message define:
|
||||||
|
message getattr {
|
||||||
|
string path = 1;
|
||||||
|
fstat stat = 2;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message setxattr {
|
||||||
|
string path = 1;
|
||||||
|
string name = 2;
|
||||||
|
bytes value = 3;
|
||||||
|
int64 size = 4;
|
||||||
|
uint32 flags = 5;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
message getxattr {
|
||||||
|
string path = 1;
|
||||||
|
string name = 2;
|
||||||
|
bytes value = 3;
|
||||||
|
int64 size = 4;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message access {
|
||||||
|
string path = 1;
|
||||||
|
uint32 mask = 2;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message readdir {
|
||||||
|
string path = 1;
|
||||||
|
repeated string dirs = 2;
|
||||||
|
uint32 offset = 3;
|
||||||
|
file_info fi = 4;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message open {
|
||||||
|
string path = 1;
|
||||||
|
file_info fi = 2;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message read {
|
||||||
|
string path = 1;
|
||||||
|
bytes buff = 2;
|
||||||
|
int64 size = 3;
|
||||||
|
int64 offset = 4;
|
||||||
|
file_info fi = 5;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message write {
|
||||||
|
string path = 1;
|
||||||
|
bytes buff = 2;
|
||||||
|
int64 size = 3;
|
||||||
|
int64 offset = 4;
|
||||||
|
file_info fi = 5;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message truncate {
|
||||||
|
string path = 1;
|
||||||
|
int64 size = 3;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message timespec {
|
||||||
|
int32 tv_sec = 1;
|
||||||
|
int64 tv_nsec = 2;
|
||||||
|
}
|
||||||
|
message utimens {
|
||||||
|
string path = 1;
|
||||||
|
repeated timespec ts = 2; // const struct timespec ts[2]
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message chown {
|
||||||
|
string path = 1;
|
||||||
|
int32 uid = 2;
|
||||||
|
int32 gid = 3;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message release {
|
||||||
|
string path = 1;
|
||||||
|
file_info fi = 2;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message mkdir {
|
||||||
|
string path = 1;
|
||||||
|
file_info fi = 2;
|
||||||
|
uint32 mode = 3;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message rmdir {
|
||||||
|
string path = 1;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message flush {
|
||||||
|
string path = 1;
|
||||||
|
file_info fi = 2;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message opendir {
|
||||||
|
string path = 1;
|
||||||
|
file_info fi = 2;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message releasedir {
|
||||||
|
string path = 1;
|
||||||
|
file_info fi = 2;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message create {
|
||||||
|
string path = 1;
|
||||||
|
uint32 mode = 2;
|
||||||
|
file_info fi = 3;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message unlink {
|
||||||
|
string path = 1;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
message rename {
|
||||||
|
string path = 1;
|
||||||
|
string new = 2;
|
||||||
|
int32 ret = 15;
|
||||||
|
}
|
19
src/client.rs
Executable file
19
src/client.rs
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
use lws_client::LwsVfsIns;
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let mut lws_ins = match LwsVfsIns::new("config.json").await{
|
||||||
|
Ok(ins) => ins,
|
||||||
|
Err(e) => {
|
||||||
|
println!("Error creating lws server instance: {:?}", e);
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match lws_ins.hello().await{
|
||||||
|
Err(e) => {
|
||||||
|
println!("lws client instance hello err {:?}", e);
|
||||||
|
return Err(e);
|
||||||
|
},
|
||||||
|
_ =>{},
|
||||||
|
}
|
||||||
|
LwsVfsIns::mount(lws_ins)
|
||||||
|
}
|
109
src/lib.rs
Normal file
109
src/lib.rs
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
use lws_client::HelloRequest;
|
||||||
|
use std::{io::Read as _};
|
||||||
|
use std::fs::File;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use serde_json::{self, Value};
|
||||||
|
use lws_client::lws_vfs_client::LwsVfsClient;
|
||||||
|
use std::os::raw::c_int;
|
||||||
|
|
||||||
|
use fuser::{
|
||||||
|
KernelConfig, FileAttr, FileType, Filesystem, MountOption, ReplyAttr, ReplyData, ReplyDirectory, ReplyEntry,
|
||||||
|
Request,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub mod lws_client {
|
||||||
|
tonic::include_proto!("lws_vfs"); //导入lws vfs proto buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct Config {
|
||||||
|
port: u16,
|
||||||
|
addr: String,
|
||||||
|
mount_map: HashMap<String, String>,
|
||||||
|
}
|
||||||
|
impl Config {
|
||||||
|
pub fn new(json: &str) -> Result<Config, Box<dyn Error>> {
|
||||||
|
let mut file = File::open(json)?;
|
||||||
|
let mut buffer = String::new();
|
||||||
|
file.read_to_string(&mut buffer)?;
|
||||||
|
let json: Value = serde_json::from_str(buffer.as_ref())?;
|
||||||
|
let port: u16 = match json.get("port") {
|
||||||
|
Some(port) => port.as_u64().expect("expect port is a number but its not") as u16,
|
||||||
|
None => 5001,
|
||||||
|
};
|
||||||
|
let addr: String = match json.get("addr") {
|
||||||
|
Some(addr) => addr.as_str().expect("expect addr is a String but its not").to_string(),
|
||||||
|
None => "localhost".to_string(),
|
||||||
|
};
|
||||||
|
let mounts = match json.get("mount") {
|
||||||
|
Some(mounts) => mounts.as_object().unwrap(),
|
||||||
|
None => {
|
||||||
|
return Err(Box::new(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::Other,
|
||||||
|
"no mount map",
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mount_map = mounts
|
||||||
|
.iter()
|
||||||
|
.map(|(key, value)| {
|
||||||
|
(
|
||||||
|
key.as_str().to_string(),
|
||||||
|
value.as_str().unwrap().to_string(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
Ok(Config { port, addr, mount_map })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_port(&self) -> u16 {
|
||||||
|
self.port
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_addr(&self) -> &String {
|
||||||
|
&self.addr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LwsVfsIns {
|
||||||
|
pub config: Config,
|
||||||
|
rpc: LwsVfsClient<tonic::transport::Channel>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Filesystem for LwsVfsIns {
|
||||||
|
fn init(&mut self, _req: &Request, #[allow(unused_variables)] config: &mut KernelConfig,
|
||||||
|
) -> Result<(), c_int> {
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LwsVfsIns {
|
||||||
|
pub async fn new(json: &str) -> Result<LwsVfsIns, Box<dyn Error>> {
|
||||||
|
let config = Config::new(json)?;
|
||||||
|
let addr = format!("http://{}:{}", config.get_addr(), config.get_port());
|
||||||
|
//connect to server
|
||||||
|
let rpc = LwsVfsClient::connect(addr).await?;
|
||||||
|
Ok(LwsVfsIns {
|
||||||
|
config,
|
||||||
|
rpc,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pub async fn hello(&mut self) -> Result<(), Box<dyn Error>> {
|
||||||
|
let request = tonic::Request::new(HelloRequest {
|
||||||
|
name: "Ekko lws hello".into(),
|
||||||
|
});
|
||||||
|
let response = &self.rpc.say_hello(request).await?;
|
||||||
|
|
||||||
|
println!("RESPONSE={:?}", response);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
pub fn mount<FS:Filesystem>(file_system:FS) -> Result<(), Box<dyn Error>> {
|
||||||
|
let mountpoint = "/mnt";
|
||||||
|
let options = vec![MountOption::RO, MountOption::FSName("lws_fs".to_string())];
|
||||||
|
fuser::mount2(file_system, mountpoint, &options).unwrap();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
3
src/main.rs
Normal file
3
src/main.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() {
|
||||||
|
println!("Hello, world!");
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user