pub use self::result::{CGroupError, Result};
use self::result::check_return;
mod result;
pub use self::iter::*;
mod iter;
pub use self::init::init;
mod init;
extern crate libcgroup_sys as ffi;
extern crate libc;
use std::ffi::{CStr, CString};
pub struct CGroup {
cgroup: *const ffi::cgroup,
}
pub struct CGroupController {
controller: *const ffi::cgroup_controller,
}
pub struct CGroupUidGid {
pub tasks_uid: u32,
pub tasks_gid: u32,
pub control_uid: u32,
pub control_gid: u32,
}
pub struct CGroupPermissions {
pub control_dperm: u32,
pub control_fperm: u32,
pub task_fperm: u32,
}
impl Drop for CGroup {
fn drop(&mut self) {
unsafe {
ffi::cgroup_free(&self.cgroup);
}
}
}
pub enum Compare {
Equal,
NotEqual,
ControllersNotEqual,
}
impl CGroup {
pub fn new<S>(name: S) -> Result<CGroup>
where S: Into<String>
{
init();
let cg = CGroup {
cgroup: unsafe { ffi::cgroup_new_cgroup(CString::new(name.into()).unwrap().as_ptr()) },
};
if cg.cgroup.is_null() {
return check_return(ffi::ECGFAIL, cg);
}
Ok(cg)
}
pub fn add_controller<S>(&self, controller: S) -> Result<CGroupController>
where S: Into<String>
{
let ctrlr = unsafe {
ffi::cgroup_add_controller(self.cgroup,
CString::new(controller.into()).unwrap().as_ptr())
};
let cgroup_controller = CGroupController { controller: ctrlr };
if ctrlr.is_null() {
return check_return(ffi::ECGFAIL, cgroup_controller);
}
Ok(cgroup_controller)
}
pub fn get_controller<S>(&self, controller: S) -> Result<CGroupController>
where S: Into<String>
{
let ctrlr = unsafe {
ffi::cgroup_get_controller(self.cgroup,
CString::new(controller.into()).unwrap().as_ptr())
};
let cgroup_controller = CGroupController { controller: ctrlr };
if ctrlr.is_null() {
return check_return(ffi::ECGFAIL, cgroup_controller);
}
Ok(cgroup_controller)
}
pub fn create(&self) -> Result<()> {
let ret = unsafe { ffi::cgroup_create_cgroup(self.cgroup, 0) };
check_return(ret, ())
}
pub fn create_from_parent(&self) -> Result<()> {
let ret = unsafe { ffi::cgroup_create_cgroup_from_parent(self.cgroup, 0) };
check_return(ret, ())
}
pub fn modify(&self) -> Result<()> {
let ret = unsafe { ffi::cgroup_modify_cgroup(self.cgroup) };
check_return(ret, ())
}
pub fn delete(&self) -> Result<()> {
let ret = unsafe { ffi::cgroup_delete_cgroup(self.cgroup, 0) };
check_return(ret, ())
}
pub fn get(&self) -> Result<()> {
let ret = unsafe { ffi::cgroup_get_cgroup(self.cgroup) };
check_return(ret, ())
}
pub fn copy(&self, dest: &CGroup) -> Result<()> {
let ret = unsafe { ffi::cgroup_copy_cgroup(self.cgroup, dest.cgroup) };
check_return(ret, ())
}
pub fn compare(&self, other: &CGroup) -> Compare {
match unsafe { ffi::cgroup_compare_cgroup(self.cgroup, other.cgroup) } {
ffi::ECGCONTROLLERNOTEQUAL => Compare::ControllersNotEqual,
ffi::ECGROUPNOTEQUAL => Compare::NotEqual,
0 => Compare::Equal,
x => panic!("Invalid return: {}", x),
}
}
pub fn set_uid_gid(&self, uid_gid: CGroupUidGid) -> Result<()> {
let ret = unsafe {
ffi::cgroup_set_uid_gid(self.cgroup,
uid_gid.tasks_uid,
uid_gid.tasks_gid,
uid_gid.control_uid,
uid_gid.control_gid)
};
check_return(ret, ())
}
pub fn get_uid_gid(&self) -> Result<CGroupUidGid> {
let (mut tasks_uid, mut tasks_gid, mut control_uid, mut control_gid) =
(0u32, 0u32, 0u32, 0u32);
let ret = unsafe {
ffi::cgroup_get_uid_gid(self.cgroup,
&mut tasks_uid,
&mut tasks_gid,
&mut control_uid,
&mut control_gid)
};
check_return(ret,
CGroupUidGid {
tasks_uid: tasks_uid,
tasks_gid: tasks_gid,
control_uid: control_uid,
control_gid: control_gid,
})
}
pub fn set_permissions(&self, perms: CGroupPermissions) {
unsafe {
ffi::cgroup_set_permissions(self.cgroup,
perms.control_dperm,
perms.control_fperm,
perms.task_fperm)
};
}
}
impl CGroupController {
pub fn compare(&self, other: &CGroupController) -> i32 {
unsafe { ffi::cgroup_compare_controllers(self.controller, other.controller) }
}
pub fn add_value_string<S>(&self, name: S, value: S) -> Result<()>
where S: Into<String>
{
let ret = unsafe {
ffi::cgroup_add_value_string(self.controller,
CString::new(name.into()).unwrap().as_ptr(),
CString::new(value.into()).unwrap().as_ptr())
};
check_return(ret, ())
}
pub fn add_value_int64<S>(&self, name: S, value: i64) -> Result<()>
where S: Into<String>
{
let ret = unsafe {
ffi::cgroup_add_value_int64(self.controller,
CString::new(name.into()).unwrap().as_ptr(),
value)
};
check_return(ret, ())
}
pub fn add_value_uint64<S>(&self, name: S, value: u64) -> Result<()>
where S: Into<String>
{
let ret = unsafe {
ffi::cgroup_add_value_uint64(self.controller,
CString::new(name.into()).unwrap().as_ptr(),
value)
};
check_return(ret, ())
}
pub fn add_value_bool<S>(&self, name: S, value: bool) -> Result<()>
where S: Into<String>
{
let ret = unsafe {
ffi::cgroup_add_value_bool(self.controller,
CString::new(name.into()).unwrap().as_ptr(),
value)
};
check_return(ret, ())
}
pub fn get_value_string<S>(&self, name: S) -> Result<String>
where S: Into<String>
{
let value: *const libc::c_char = std::ptr::null();
let ret = unsafe {
ffi::cgroup_get_value_string(self.controller,
CString::new(name.into()).unwrap().as_ptr(),
&value as *const *const libc::c_char)
};
check_return(ret,
unsafe { CStr::from_ptr(value).to_string_lossy().into_owned() })
}
pub fn get_value_int64<S>(&self, name: S) -> Result<i64>
where S: Into<String>
{
let value = 0i64;
let ret = unsafe {
ffi::cgroup_get_value_int64(self.controller,
CString::new(name.into()).unwrap().as_ptr(),
&value)
};
check_return(ret, value)
}
pub fn get_value_uint64<S>(&self, name: S) -> Result<u64>
where S: Into<String>
{
let value = 0u64;
let ret = unsafe {
ffi::cgroup_get_value_uint64(self.controller,
CString::new(name.into()).unwrap().as_ptr(),
&value)
};
check_return(ret, value)
}
pub fn get_value_bool<S>(&self, name: S) -> Result<bool>
where S: Into<String>
{
let value = false;
let ret = unsafe {
ffi::cgroup_get_value_bool(self.controller,
CString::new(name.into()).unwrap().as_ptr(),
&value)
};
check_return(ret, value)
}
pub fn set_value_string<S>(&self, name: S, value: S) -> Result<*const CGroupController>
where S: Into<String>
{
let ret = unsafe {
ffi::cgroup_set_value_string(self.controller,
CString::new(name.into()).unwrap().as_ptr(),
CString::new(value.into()).unwrap().as_ptr())
};
check_return(ret, self)
}
pub fn set_value_int64<S>(&self, name: S, value: i64) -> Result<*const CGroupController>
where S: Into<String>
{
let ret = unsafe {
ffi::cgroup_set_value_int64(self.controller,
CString::new(name.into()).unwrap().as_ptr(),
value)
};
check_return(ret, self)
}
pub fn set_value_uint64<S>(&self, name: S, value: u64) -> Result<*const CGroupController>
where S: Into<String>
{
let ret = unsafe {
ffi::cgroup_set_value_uint64(self.controller,
CString::new(name.into()).unwrap().as_ptr(),
value)
};
check_return(ret, self)
}
pub fn set_value_bool<S>(&self, name: S, value: bool) -> Result<*const CGroupController>
where S: Into<String>
{
let ret = unsafe {
ffi::cgroup_set_value_bool(self.controller,
CString::new(name.into()).unwrap().as_ptr(),
value)
};
check_return(ret, self)
}
}