use lazy_static::lazy_static;
use std::sync::Mutex;
use nbdkit::*;
lazy_static! {
static ref SIZE : Mutex<usize> = Mutex::new(100 * 1024 * 1024);
static ref DISK : Mutex<Vec<u8>> = Mutex::new(vec![0;0]);
}
#[derive(Default)]
struct RamDisk {
_not_used: i32,
}
impl Server for RamDisk {
fn name() -> &'static str {
"ramdisk"
}
fn config(key: &str, val: &str) -> Result<()> {
match key {
"size" => {
*SIZE.lock().unwrap() = parse_size(val).unwrap() as usize;
Ok(())
},
_ => Err(Error::new(libc::EINVAL, "Unknown parameter"))
}
}
fn get_ready() -> Result<()> {
*DISK.lock().unwrap() = vec![0; *SIZE.lock().unwrap()];
Ok(())
}
fn open(_readonly: bool) -> Result<Box<dyn Server>> {
let tls = is_tls().unwrap();
debug!("connection opened: readonly={}, tls={}", _readonly, tls);
Ok(Box::<RamDisk>::default())
}
fn get_size(&self) -> Result<i64> {
Ok(DISK.lock().unwrap().len() as i64)
}
fn read_at(&self, buf: &mut [u8], offset: u64) -> Result<()> {
let disk = DISK.lock().unwrap();
let ofs = offset as usize;
let end = ofs + buf.len();
buf.copy_from_slice(&disk[ofs..end]);
Ok(())
}
fn thread_model() -> Result<ThreadModel> where Self: Sized {
Ok(ThreadModel::Parallel)
}
fn write_at(&self, buf: &[u8], offset: u64, _flags: Flags) -> Result<()> {
let mut disk = DISK.lock().unwrap();
let ofs = offset as usize;
let end = ofs + buf.len();
disk[ofs..end].copy_from_slice(buf);
Ok(())
}
}
plugin!(RamDisk {thread_model, write_at, config, get_ready});