src/api2/admin/datastore/backup/environment.rs: register/lookup known chunks
This commit is contained in:
		| @ -261,11 +261,10 @@ fn dynamic_append ( | ||||
|  | ||||
|     let env: &BackupEnvironment = rpcenv.as_ref(); | ||||
|  | ||||
|     let _size = 0; | ||||
|     let _digest = crate::tools::hex_to_digest(digest_str)?; | ||||
|     let digest = crate::tools::hex_to_digest(digest_str)?; | ||||
|     let size = env.lookup_chunk(&digest).ok_or_else(|| format_err!("no such chunk"))?; | ||||
|  | ||||
|     // fixme: lookup digest and chunk size, then add | ||||
|     //env.dynamic_writer_append_chunk(wid, size, &digest)?; | ||||
|     env.dynamic_writer_append_chunk(wid, size, &digest)?; | ||||
|  | ||||
|     env.log(format!("sucessfully added chunk {} to dynamic index {}", digest_str, wid)); | ||||
|  | ||||
|  | ||||
| @ -14,6 +14,7 @@ struct SharedBackupState { | ||||
|     finished: bool, | ||||
|     uid_counter: usize, | ||||
|     dynamic_writers: HashMap<usize, (u64 /* offset */, DynamicIndexWriter)>, | ||||
|     known_chunks: HashMap<[u8;32], u32>, | ||||
| } | ||||
|  | ||||
| impl SharedBackupState { | ||||
| @ -61,6 +62,7 @@ impl BackupEnvironment { | ||||
|             finished: false, | ||||
|             uid_counter: 0, | ||||
|             dynamic_writers: HashMap::new(), | ||||
|             known_chunks: HashMap::new(), | ||||
|         }; | ||||
|  | ||||
|         Self { | ||||
| @ -76,6 +78,27 @@ impl BackupEnvironment { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Register a Chunk with associated length. A client may only use registered | ||||
|     // chunks (we do not trust clients that far ...) | ||||
|     pub fn register_chunk(&self, digest: [u8; 32], length: u32) -> Result<(), Error> { | ||||
|         let mut state = self.state.lock().unwrap(); | ||||
|  | ||||
|         state.ensure_unfinished()?; | ||||
|  | ||||
|         state.known_chunks.insert(digest, length); | ||||
|  | ||||
|         Ok(()) | ||||
|     } | ||||
|  | ||||
|     pub fn lookup_chunk(&self, digest: &[u8; 32]) -> Option<u32> { | ||||
|         let state = self.state.lock().unwrap(); | ||||
|  | ||||
|         match state.known_chunks.get(digest) { | ||||
|             Some(len) => Some(*len), | ||||
|             None => None, | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /// Store the writer with an unique ID | ||||
|     pub fn register_dynamic_writer(&self, writer: DynamicIndexWriter) -> Result<usize, Error> { | ||||
|         let mut state = self.state.lock().unwrap(); | ||||
| @ -90,7 +113,7 @@ impl BackupEnvironment { | ||||
|     } | ||||
|  | ||||
|     /// Append chunk to dynamic writer | ||||
|     pub fn dynamic_writer_append_chunk(&self, wid: usize, size: u64, digest: &[u8; 32]) -> Result<(), Error> { | ||||
|     pub fn dynamic_writer_append_chunk(&self, wid: usize, size: u32, digest: &[u8; 32]) -> Result<(), Error> { | ||||
|         let mut state = self.state.lock().unwrap(); | ||||
|  | ||||
|         state.ensure_unfinished()?; | ||||
| @ -100,7 +123,7 @@ impl BackupEnvironment { | ||||
|             None => bail!("dynamic writer '{}' not registered", wid), | ||||
|         }; | ||||
|  | ||||
|         data.0 += size; | ||||
|         data.0 += size as u64; | ||||
|  | ||||
|         data.1.add_chunk(data.0, digest)?; | ||||
|  | ||||
|  | ||||
| @ -16,22 +16,22 @@ use super::environment::*; | ||||
| pub struct UploadChunk { | ||||
|     stream: Body, | ||||
|     store: Arc<DataStore>, | ||||
|     size: u64, | ||||
|     size: u32, | ||||
|     chunk: Vec<u8>, | ||||
| } | ||||
|  | ||||
| impl UploadChunk { | ||||
|  | ||||
|     pub fn new(stream: Body,  store: Arc<DataStore>, size: u64) -> Self { | ||||
|     pub fn new(stream: Body,  store: Arc<DataStore>, size: u32) -> Self { | ||||
|         Self { stream, store, size, chunk: vec![] } | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl Future for UploadChunk { | ||||
|     type Item = ([u8; 32], u64); | ||||
|     type Item = ([u8; 32], u32); | ||||
|     type Error = failure::Error; | ||||
|  | ||||
|     fn poll(&mut self) -> Poll<([u8; 32], u64), failure::Error> { | ||||
|     fn poll(&mut self) -> Poll<([u8; 32], u32), failure::Error> { | ||||
|         loop { | ||||
|             match try_ready!(self.stream.poll()) { | ||||
|                 Some(chunk) => { | ||||
| @ -77,19 +77,20 @@ fn upload_dynamic_chunk( | ||||
|     rpcenv: Box<RpcEnvironment>, | ||||
| ) -> Result<BoxFut, Error> { | ||||
|  | ||||
|     let size = tools::required_integer_param(¶m, "size")?; | ||||
|     let size = tools::required_integer_param(¶m, "size")? as u32; | ||||
|     let wid = tools::required_integer_param(¶m, "wid")? as usize; | ||||
|  | ||||
|  | ||||
|     let env: &BackupEnvironment = rpcenv.as_ref(); | ||||
|  | ||||
|     let upload = UploadChunk::new(req_body, env.datastore.clone(), size as u64); | ||||
|     let upload = UploadChunk::new(req_body, env.datastore.clone(), size); | ||||
|  | ||||
|     let resp = upload | ||||
|         .then(move |result| { | ||||
|             let env: &BackupEnvironment = rpcenv.as_ref(); | ||||
|  | ||||
|             let result = result.and_then(|(digest, size)| { | ||||
|                 env.register_chunk(digest, size)?; | ||||
|                 env.dynamic_writer_append_chunk(wid, size, &digest)?; | ||||
|                 Ok(json!(tools::digest_to_hex(&digest))) | ||||
|             }); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user