Commit 536df992 authored by Heinz N. Gies's avatar Heinz N. Gies

More resource restrictions

parent 832e59fb
This diff is collapsed.
//! Jail Configuration
use std::error::Error;
use std::fs::File;
use std::io::Read;
use serde_json;
use uuid::Uuid;
/// Jail configuration values
#[derive(Debug, Serialize, Deserialize)]
pub struct JailConfig {
/// UUID of the jail
#[serde(default = "new_uuid")]
pub uuid: String,
/// UUID of the imaage
pub image_uuid: String,
/// readable alias for the jail
pub alias: String,
/// hostname of the jail
pub hostname: String,
/// weather to start this jail on --startup
pub autostart: Option<bool>,
// Resources
/// max physical memory in MB (memoryuse)
pub max_physical_memory: u64,
/// mac cpu usage 100 = 1 core (pcpu)
pub cpu_cap: u64,
/// max quota (zfs quota)
quota: u64,
/// SysV shared memory size, in bytes (shmsize)
pub max_shm_memory: Option<u64>,
/// locked memory (memorylocked)
pub max_locked_memory: Option<u64>,
/// maximum number of porocesses (maxproc)
#[serde(default = "dflt_max_lwp")]
pub max_lwps: u64,
}
impl JailConfig {
/// Reads a new config from a file
pub fn from_file(config_path: &str) -> Result<Self, Box<Error>> {
let config_file = File::open(config_path)?;
JailConfig::from_reader(config_file)
}
/// Reads the config from a reader
pub fn from_reader<R>(reader: R) -> Result<Self, Box<Error>>
where
R: Read,
{
let mut conf: JailConfig = serde_json::from_reader(reader)?;
let max_physical_memory = conf.max_physical_memory;
if conf.max_shm_memory.is_none() {
conf.max_shm_memory = Some(max_physical_memory);
}
if conf.max_locked_memory.is_none() {
conf.max_locked_memory = Some(max_physical_memory);
}
if conf.autostart.is_none() {
conf.autostart = Some(false);
}
Ok(conf)
}
/// Translates the config into resource controle limts
pub fn rctl_limits(self: &JailConfig) -> Vec<String> {
let mut res = Vec::new();
let uuid = self.uuid.clone();
let mut base = String::from("jail:");
base.push_str(uuid.as_str());
let max_physical_memory = self.max_physical_memory.to_string();
let mut mem = base.clone();
mem.push_str(":memoryuse:deny=");
mem.push_str(max_physical_memory.as_str());
mem.push_str("M");
res.push(mem);
let mut memorylocked = base.clone();
memorylocked.push_str(":memorylocked:deny=");
match self.max_locked_memory {
Some(max_locked_memory) => {
memorylocked.push_str(max_locked_memory.to_string().as_str())
}
None => memorylocked.push_str(max_physical_memory.as_str()),
}
memorylocked.push_str("M");
res.push(memorylocked);
let mut shmsize = base.clone();
shmsize.push_str(":shmsize:deny=");
match self.max_shm_memory {
Some(max_shm_memory) => shmsize.push_str(max_shm_memory.to_string().as_str()),
None => shmsize.push_str(max_physical_memory.as_str()),
}
shmsize.push_str("M");
res.push(shmsize);
let mut pcpu = base.clone();
pcpu.push_str(":pcpu:deny=");
pcpu.push_str(self.cpu_cap.to_string().as_str());
res.push(pcpu);
let mut maxproc = base.clone();
maxproc.push_str(":maxproc:deny=");
maxproc.push_str(self.max_lwps.to_string().as_str());
res.push(maxproc);
res
}
}
fn dflt_max_lwp() -> u64 {
2000
}
fn new_uuid() -> String {
Uuid::new_v4().hyphenated().to_string()
}
\ No newline at end of file
......@@ -27,7 +27,7 @@ static JAIL: &'static str = "echo";
/// starts a jail
pub fn start(jail: &Jail) -> Result<i32, Box<Error>> {
let args = create_args(jail);
let limits = rctl_limits(jail);
let limits = jail.config.rctl_limits();
debug!("Setting jail limits"; "vm" => jail.idx.uuid.clone());
let output = Command::new(RCTL).args(limits).output().expect(
"limit failed",
......@@ -45,24 +45,6 @@ pub fn start(jail: &Jail) -> Result<i32, Box<Error>> {
}
fn rctl_limits(jail: &Jail) -> Vec<String> {
let uuid = jail.config.uuid.clone();
let mut base = String::from("jail:");
base.push_str(uuid.as_str());
let mut mem = base.clone();
mem.push_str(":memoryuse:deny=");
mem.push_str(jail.config.max_physical_memory.to_string().as_str());
mem.push_str("M");
let mut pcpu = base.clone();
pcpu.push_str(":pcpu:deny=");
pcpu.push_str(jail.config.cpu_cap.to_string().as_str());
vec![String::from("-a"), mem, pcpu]
}
fn create_args(jail: &Jail) -> Vec<String> {
let uuid = jail.idx.uuid.clone();
let mut name = String::from("name=");
......
......@@ -7,41 +7,15 @@ use std::path::PathBuf;
use std::str;
use std::cmp::PartialEq;
use std::collections::HashMap;
use uuid::Uuid;
use serde_json;
use jails;
use jail_config::JailConfig;
use errors::{NotFoundError, ConflictError};
use errors::{NotFoundError, ConflictError, GenericError};
use config::Config;
/// Jail configuration values
#[derive(Debug, Serialize, Deserialize)]
pub struct JailConfig {
/// UUID of the jail
#[serde(default = "new_uuid")]
pub uuid: String,
/// UUID of the imaage
pub image_uuid: String,
/// readable alias for the jail
pub alias: String,
/// hostname of the jail
pub hostname: String,
/// max physical memory in MB
pub max_physical_memory: u64,
/// mac cpu usage 100 = 1 core
pub cpu_cap: u64,
/// max quota (zfs quota)
quota: u64,
autostart: Option<bool>,
}
fn new_uuid() -> String {
Uuid::new_v4().hyphenated().to_string()
}
/// `JailDB` index entry
#[derive(Debug, Serialize, Deserialize)]
pub struct IdxEntry {
......@@ -54,7 +28,6 @@ pub struct IdxEntry {
jail_type: String,
}
/// Jail config
pub struct Jail<'a> {
/// Index refference
......@@ -215,9 +188,10 @@ impl<'a> JDB<'a> {
let mut config_path = PathBuf::from(self.config.settings.conf_dir.as_str());
config_path.push(entry.uuid.clone());
config_path.set_extension("json");
let config_file = File::open(config_path)?;
let conf: JailConfig = serde_json::from_reader(config_file)?;
Ok(conf)
match config_path.to_str() {
Some(path) => JailConfig::from_file(path),
None => Err(GenericError::bx("could not generate vm config path")),
}
}
/// Saves the database
fn save(self: &'a JDB<'a>) -> Result<usize, Box<Error>> {
......
......@@ -39,6 +39,8 @@ mod zfs;
pub mod jails;
pub mod jail_config;
pub mod jdb;
use jdb::JDB;
......@@ -216,7 +218,7 @@ fn list(conf: &Config, _matches: &clap::ArgMatches) -> Result<i32, Box<Error>> {
fn create(conf: &Config, _matches: &clap::ArgMatches) -> Result<i32, Box<Error>> {
let mut db = JDB::open(conf)?;
let jail: jdb::JailConfig = serde_json::from_reader(io::stdin())?;
let jail = jail_config::JailConfig::from_reader(io::stdin())?;
let mut dataset = conf.settings.pool.clone();
dataset.push('/');
dataset.push_str(jail.image_uuid.clone().as_str());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment