2021-05-04 13:40:20 +05:30
|
|
|
use anyhow::Result;
|
2020-08-07 19:00:00 +05:30
|
|
|
use rand::prelude::*;
|
|
|
|
use std::collections::HashSet;
|
|
|
|
use std::fs::OpenOptions;
|
|
|
|
use std::path::Path;
|
2021-07-08 14:34:40 +05:30
|
|
|
use thinp::cache::ir::{self, MetadataVisitor};
|
2020-08-07 19:00:00 +05:30
|
|
|
use thinp::cache::xml;
|
|
|
|
|
|
|
|
//------------------------------------------
|
|
|
|
|
|
|
|
pub trait XmlGen {
|
2021-07-08 14:34:40 +05:30
|
|
|
fn generate_xml(&mut self, v: &mut dyn MetadataVisitor) -> Result<()>;
|
2020-08-07 19:00:00 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
pub fn write_xml(path: &Path, g: &mut dyn XmlGen) -> Result<()> {
|
|
|
|
let xml_out = OpenOptions::new()
|
|
|
|
.read(false)
|
|
|
|
.write(true)
|
|
|
|
.create(true)
|
|
|
|
.truncate(true)
|
|
|
|
.open(path)?;
|
|
|
|
let mut w = xml::XmlWriter::new(xml_out);
|
|
|
|
|
|
|
|
g.generate_xml(&mut w)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct CacheGen {
|
2021-02-25 15:44:01 +05:30
|
|
|
block_size: u32,
|
|
|
|
nr_cache_blocks: u32,
|
2020-08-07 19:00:00 +05:30
|
|
|
nr_origin_blocks: u64,
|
|
|
|
percent_resident: u8,
|
|
|
|
percent_dirty: u8,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl CacheGen {
|
|
|
|
pub fn new(
|
2021-02-25 15:44:01 +05:30
|
|
|
block_size: u32,
|
|
|
|
nr_cache_blocks: u32,
|
2020-08-07 19:00:00 +05:30
|
|
|
nr_origin_blocks: u64,
|
|
|
|
percent_resident: u8,
|
|
|
|
percent_dirty: u8,
|
|
|
|
) -> Self {
|
|
|
|
CacheGen {
|
|
|
|
block_size,
|
|
|
|
nr_cache_blocks,
|
|
|
|
nr_origin_blocks,
|
|
|
|
percent_resident,
|
|
|
|
percent_dirty,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl XmlGen for CacheGen {
|
2021-07-08 14:34:40 +05:30
|
|
|
fn generate_xml(&mut self, v: &mut dyn MetadataVisitor) -> Result<()> {
|
|
|
|
v.superblock_b(&ir::Superblock {
|
2020-08-07 19:00:00 +05:30
|
|
|
uuid: "".to_string(),
|
|
|
|
block_size: self.block_size,
|
|
|
|
nr_cache_blocks: self.nr_cache_blocks,
|
|
|
|
policy: "smq".to_string(),
|
|
|
|
hint_width: 4,
|
|
|
|
})?;
|
|
|
|
|
|
|
|
let mut cblocks = Vec::new();
|
|
|
|
for n in 0..self.nr_cache_blocks {
|
|
|
|
cblocks.push(n);
|
|
|
|
}
|
|
|
|
cblocks.shuffle(&mut rand::thread_rng());
|
|
|
|
|
|
|
|
v.mappings_b()?;
|
|
|
|
{
|
2021-05-25 12:48:52 +05:30
|
|
|
let nr_resident = (self.nr_cache_blocks * 100u32) / (self.percent_resident as u32);
|
2020-08-07 19:00:00 +05:30
|
|
|
let mut used = HashSet::new();
|
|
|
|
for n in 0..nr_resident {
|
|
|
|
let mut oblock = 0u64;
|
|
|
|
while used.contains(&oblock) {
|
|
|
|
oblock = rand::thread_rng().gen();
|
|
|
|
}
|
|
|
|
|
|
|
|
used.insert(oblock);
|
|
|
|
// FIXME: dirty should vary
|
2021-07-08 14:34:40 +05:30
|
|
|
v.mapping(&ir::Map {
|
2020-08-07 19:00:00 +05:30
|
|
|
cblock: cblocks[n as usize],
|
|
|
|
oblock,
|
|
|
|
dirty: false,
|
|
|
|
})?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
v.mappings_e()?;
|
|
|
|
|
|
|
|
v.superblock_e()?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------
|