Skip to content

Commit

Permalink
Try adding fuse module for index
Browse files Browse the repository at this point in the history
  • Loading branch information
GamePad64 committed Nov 17, 2021
1 parent e1f1c94 commit c7fa11e
Show file tree
Hide file tree
Showing 17 changed files with 286 additions and 108 deletions.
46 changes: 44 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 13 additions & 13 deletions cmake/MakeCxxBridge.cmake
@@ -1,16 +1,3 @@
macro(expand_config_genex EXPANDED_LIST GENEX_LIST)
if(CMAKE_CONFIGURATION_TYPES)
foreach(config ${CMAKE_CONFIGURATION_TYPES})
foreach(src_genex ${GENEX_LIST})
string(REPLACE "$<CONFIG>" "${config}" expanded_src "${src_genex}")
list(APPEND ${EXPANDED_LIST} "${expanded_src}")
endforeach()
endforeach()
else()
set(${EXPANDED_LIST} "${GENEX_LIST}")
endif()
endmacro()

macro(add_cxxbridge CXXBRIDGE_LIBRARY_NAME CXXBRIDGES_TXT CRATE_NAME)
if (CMAKE_VS_PLATFORM_NAME)
set (build_dir "${CMAKE_VS_PLATFORM_NAME}/$<CONFIG>")
Expand All @@ -37,3 +24,16 @@ macro(add_cxxbridge CXXBRIDGE_LIBRARY_NAME CXXBRIDGES_TXT CRATE_NAME)
set_target_properties(${CXXBRIDGE_LIBRARY_NAME} PROPERTIES LINKER_LANGUAGE CXX)
target_include_directories(${CXXBRIDGE_LIBRARY_NAME} INTERFACE "${CXXBRIDGE_ROOT}")
endmacro()

macro(expand_config_genex EXPANDED_LIST GENEX_LIST)
if(CMAKE_CONFIGURATION_TYPES)
foreach(config ${CMAKE_CONFIGURATION_TYPES})
foreach(src_genex ${GENEX_LIST})
string(REPLACE "$<CONFIG>" "${config}" expanded_src "${src_genex}")
list(APPEND ${EXPANDED_LIST} "${expanded_src}")
endforeach()
endforeach()
else()
set(${EXPANDED_LIST} "${GENEX_LIST}")
endif()
endmacro()
5 changes: 3 additions & 2 deletions src/daemon-rs/Cargo.toml
Expand Up @@ -13,14 +13,15 @@ directories = "4.0.1"
tokio = { version = "1.13.0", features = ["rt", "macros", "rt-multi-thread", "fs", "sync", "net", "signal"] }
#igd = { version = "0.12.0", features = ["aio"] }
futures = "0.3.17"
serde_json = "1"
tonic = "0.6.1"
prost = "0.9.0"
tonic-reflection = "0.3.0"
hex = "0.4.3"
env_logger = "0.9.0"
libp2p = { version = "0.40.0", features = ["tcp-tokio", "gossipsub", "mplex", "yamux", "noise", "mdns"], default-features = false }
built = "0.5"

[target.'cfg(unix)'.dependencies]
fuse_mt = { git = "https://github.com/wfraser/fuse-mt" }

[build-dependencies]
tonic-build = "0.6.0"
Expand Down
10 changes: 10 additions & 0 deletions src/daemon-rs/src/bucket/collection.rs
Expand Up @@ -37,6 +37,16 @@ impl BucketCollection {
(*inner_lock).buckets_byid.get(bucket_id).cloned()
}

pub fn get_bucket_one(&self) -> Option<Arc<Bucket>> {
let inner_lock = self.inner.read().unwrap();
(*inner_lock)
.buckets_byid
.iter()
.next()
.map(|x| x.1)
.cloned()
}

// pub fn drop_bucket(&mut self, bucket: Arc<Bucket>) -> Option<Arc<Bucket>> {
// self.buckets_byid.remove(bucket.get_id().as_slice())
// }
Expand Down
39 changes: 21 additions & 18 deletions src/daemon-rs/src/bucket/manager.rs
Expand Up @@ -7,62 +7,65 @@ use tokio::sync::{broadcast, mpsc};

#[derive(Clone, Debug)]
pub enum BucketManagerEvent {
BucketAdded(Arc<Bucket>),
BucketRemoved(Arc<Bucket>),
Added(Arc<Bucket>),
Removed(Arc<Bucket>),
BucketEvent {
bucket: Arc<Bucket>,
event: BucketEvent,
},
}

pub struct BucketManager {
buckets: Arc<RwLock<BucketCollection>>,
event_sender: broadcast::Sender<BucketManagerEvent>,
buckets: RwLock<BucketCollection>,
event_tx: broadcast::Sender<BucketManagerEvent>,
}

impl BucketManager {
pub fn new() -> Self {
let (event_sender, _) = broadcast::channel(128);
let (event_tx, _) = broadcast::channel(128);
BucketManager {
buckets: Arc::new(RwLock::new(BucketCollection::new())),
event_sender,
buckets: RwLock::new(BucketCollection::new()),
event_tx,
}
}

pub async fn add_bucket(&self, config: BucketConfig) {
let mut lock = self.buckets.write().unwrap();

let (event_sender_bucket, mut event_receiver_bucket) = mpsc::channel(128);
let (bucket_event_tx, mut bucket_event_rx) = mpsc::channel(128);

let bucket = Bucket::new(config, event_sender_bucket).await;
let bucket = Bucket::new(config, bucket_event_tx).await;
let bucket_arc = (*lock).add_bucket(bucket);
bucket_arc.initialize().await;
trace!("Sending event for BucketAdded");

let _ = self
.event_sender
.send(BucketManagerEvent::BucketAdded(bucket_arc.clone()));
.event_tx
.send(BucketManagerEvent::Added(bucket_arc.clone()));

let event_sender_local = self.event_sender.clone();
let event_tx_cloned = self.event_tx.clone();

tokio::spawn(async move {
loop {
tokio::select! {
event = event_receiver_bucket.recv() => {
if let Some(event) = event {
event_sender_local.send(BucketManagerEvent::BucketEvent {bucket: bucket_arc.clone(), event});
} else { break; }
}
Some(event) = bucket_event_rx.recv() => {
let _ = event_tx_cloned.send(BucketManagerEvent::BucketEvent {bucket: bucket_arc.clone(), event});
},
else => break,
}
}
});
}

pub fn get_event_channel(&self) -> broadcast::Receiver<BucketManagerEvent> {
self.event_sender.subscribe()
self.event_tx.subscribe()
}

pub fn get_bucket_byid(&self, bucket_id: &[u8]) -> Option<Arc<Bucket>> {
self.buckets.read().unwrap().get_bucket_byid(bucket_id)
}

pub fn get_bucket_one(&self) -> Option<Arc<Bucket>> {
self.buckets.read().unwrap().get_bucket_one()
}
}
20 changes: 11 additions & 9 deletions src/daemon-rs/src/bucket/mod.rs
@@ -1,6 +1,5 @@
use std::borrow::Cow;
use std::fmt;
use std::fmt::Formatter;
use std::fmt::{Debug, Formatter};
use std::path::{Path, PathBuf};
use std::sync::Arc;

Expand All @@ -12,6 +11,7 @@ pub mod manager;

use crate::settings::BucketConfig;
// use librevault_util::index::proto::Meta;
use librevault_util::enc_storage::EncryptedStorage;
use librevault_util::indexer::{make_meta, sign_meta};
use log::debug;
use tokio::sync::mpsc;
Expand All @@ -22,16 +22,17 @@ pub enum BucketEvent {
}

pub struct Bucket {
secret: Secret,
pub secret: Secret,
root: PathBuf,

index: Arc<Index>,
pub index: Arc<Index>,
block_storage: EncryptedStorage,

event_sender: mpsc::Sender<BucketEvent>,
event_tx: mpsc::Sender<BucketEvent>,
}

impl Bucket {
async fn new(config: BucketConfig, event_sender: mpsc::Sender<BucketEvent>) -> Self {
async fn new(config: BucketConfig, event_tx: mpsc::Sender<BucketEvent>) -> Self {
debug!("Creating bucket: {}", config.secret.get_id_hex());

let system_dir = config.path.join(".librevault");
Expand All @@ -43,7 +44,8 @@ impl Bucket {
secret: config.secret,
root: config.path,
index,
event_sender,
block_storage: EncryptedStorage::new(&system_dir),
event_tx,
}
}

Expand All @@ -70,15 +72,15 @@ impl Bucket {
let signed_meta = sign_meta(&meta, &self.secret);
self.index.put_meta(&signed_meta, true).unwrap();

self.event_sender
self.event_tx
.send(BucketEvent::MetaAdded { signed_meta })
.await
.expect("Channel must be open");
}
}
}

impl fmt::Debug for Bucket {
impl Debug for Bucket {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "(Bucket: id={}, loc={:?})", self.get_id_hex(), self.root)
}
Expand Down
63 changes: 63 additions & 0 deletions src/daemon-rs/src/lvfs.rs
@@ -0,0 +1,63 @@
use crate::bucket::Bucket;
use fuse_mt::{DirectoryEntry, FileType, FilesystemMT, RequestInfo, ResultEntry, ResultReaddir};
use librevault_util::aescbc::decrypt_aes256;
use librevault_util::indexer::proto;
use librevault_util::path_normalize::denormalize;
use librevault_util::secret::Secret;
use std::path::Path;
use std::sync::Arc;

pub(crate) struct LibrevaultFs {
bucket: Arc<Bucket>,
}

fn make_decrypted(data: &proto::AesCbc, secret: &Secret) -> Vec<u8> {
decrypt_aes256(&*data.ct, secret.get_symmetric_key().unwrap(), &*data.iv)
}

fn meta_kind(meta: &proto::Meta) -> Option<FileType> {
match meta.meta_type {
1 => Some(FileType::RegularFile),
2 => Some(FileType::Directory),
3 => Some(FileType::Symlink),
_ => None,
}
}

impl LibrevaultFs {
pub(crate) fn new(bucket: Arc<Bucket>) -> Self {
LibrevaultFs { bucket }
}
}

impl FilesystemMT for LibrevaultFs {
fn getattr(&self, _req: RequestInfo, _path: &Path, _fh: Option<u64>) -> ResultEntry {
todo!()
}

fn readdir(&self, _req: RequestInfo, _path: &Path, _fh: u64) -> ResultReaddir {
let path = _path.strip_prefix("/").unwrap();

let mut res = vec![];

for signed_meta in self.bucket.index.get_meta_all().unwrap() {
let meta = signed_meta.parsed_meta();
let decrypted_path = make_decrypted(&meta.path.as_ref().unwrap(), &self.bucket.secret);
let denorm_path = denormalize(&*decrypted_path, None).unwrap();
if let Ok(unprefixed_path) = denorm_path.strip_prefix(path) {
let next_component = unprefixed_path.components().next().unwrap().as_os_str();

let kind = match meta_kind(&meta) {
Some(kind) => kind,
_ => continue,
};

res.push(DirectoryEntry {
name: next_component.into(),
kind,
});
}
}
Ok(res)
}
}

0 comments on commit c7fa11e

Please sign in to comment.