adding cgroup and controller bits, and comments too

This commit is contained in:
Vincent Batts 2013-12-17 15:33:03 -05:00
parent ad7c28995e
commit 8a1807ae2f
1 changed files with 161 additions and 10 deletions

171
cg.go
View File

@ -1,13 +1,155 @@
package cgroup
// #include <libcgroup.h>
// #cgo LDFLAGS: -lcgroup
/*
#include <libcgroup.h>
#cgo LDFLAGS: -lcgroup
// work around for the 'type' special word
enum cgroup_file_type type_from_file_info(struct cgroup_file_info fi) {
return fi.type;
}
*/
import "C"
import (
"errors"
"runtime"
"unsafe"
)
/*
* Structure describing one or more control groups. The structure is opaque to
* applications.
*/
type Cgroup struct {
g *C.struct_group
}
func NewCgroup(name string) Cgroup {
cg := Cgroup{
C.cgroup_new_cgroup(C.CString(name)),
}
runtime.SetFinalizer(cg, freeCgroup)
return cg
}
func (cg *Cgroup) AddController(name string) Controller {
return Controller{
C.cgroup_add_controller(cg.g, C.CString(name)),
}
}
func (cg Cgroup) GetController(name string) Controller {
return Controller{
C.cgroup_get_controller(cg.g, C.CString(name)),
}
}
func freeCgroup(cg Cgroup) {
C.cgroup_free(&cg.g)
}
/*
* Structure describing a controller attached to one struct @c cgroup, including
* parameters of the group and their values. The structure is opaque to
* applications.
*/
type Controller struct {
c *C.struct_cgroup_controller
}
/**
* Initialize libcgroup. Information about mounted hierarchies are examined
* and cached internally (just what's mounted where, not the groups themselves).
*/
func Init() error {
return _err(C.cgroup_init())
}
/*
* Load configuration file and mount and create control groups described there.
* See cgconfig.conf man page for format of the file.
*/
func LoadConfig(filename string) error {
return _err(C.cgroup_config_load_config(C.CString(filename)))
}
/**
* Delete all control groups and unmount all hierarchies.
*/
func Unload() error {
return _err(C.cgroup_unload_cgroups())
}
type DeleteFlag int
const (
/**
* Ignore errors caused by migration of tasks to parent group.
*/
DeleteIgnoreMigration = DeleteFlag(C.CGFLAG_DELETE_IGNORE_MIGRATION)
/**
* Recursively delete all child groups.
*/
DeleteRecursive = DeleteFlag(C.CGFLAG_DELETE_RECURSIVE)
/**
* Delete the cgroup only if it is empty, i.e. it has no subgroups and
* no processes inside. This flag cannot be used with
* DeleteRecursive
*/
DeleteEmptyOnly = DeleteFlag(C.CGFLAG_DELETE_EMPTY_ONLY)
)
/**
* Delete all cgroups and unmount all mount points defined in specified config
* file.
*
* The groups are either removed recursively or only the empty ones, based
* on given flags. Mount point are always umounted only if they are empty,
* regardless of any flags.
*
* The groups are sorted before they are removed, so the removal of empty ones
* actually works (i.e. subgroups are removed first).
*/
func UnloadFromConfig(filename string, flags DeleteFlag) error {
return _err(C.cgroup_config_unload_config(C.CString(filename), C.int(flags)))
}
type FileInfo struct {
Type FileType
Path string
Parent string
FullPath string
Depth int8
}
func fromCFileInfo(cData C.struct_cgroup_file_info) FileInfo {
return FileInfo{
Type: FileType(C.type_from_file_info(cData)),
Path: C.GoString(cData.path),
Parent: C.GoString(cData.parent),
FullPath: C.GoString(cData.full_path),
Depth: int8(cData.depth),
}
}
type FileType int
const (
FileTypeFile = FileType(C.CGROUP_FILE_TYPE_FILE)
FileTypeDir = FileType(C.CGROUP_FILE_TYPE_DIR)
FileTypeOther = FileType(C.CGROUP_FILE_TYPE_OTHER)
)
/*
int cgroup_walk_tree_begin(const char *controller, const char *base_path, int depth,
void **handle, struct cgroup_file_info *info,
int *base_level);
*/
/*
Information model for Controllers available
*/
type ControllerData struct {
Name string
Hierarchy int
@ -16,10 +158,11 @@ type ControllerData struct {
}
func fromCControllerData(cData C.struct_controller_data) ControllerData {
name := C.GoString(&cData.name[0])
return ControllerData{
Name: name,
Hierarchy: int(cData.hierarchy),
Name: C.GoString(&cData.name[0]),
Hierarchy: int(cData.hierarchy),
NumCgroups: int(cData.num_cgroups),
Enabled: int(cData.enabled),
}
}
@ -58,19 +201,27 @@ func GetSubSysMountPoint(controller string) (string, error) {
}
var (
ECGEOF = errors.New(C.GoString(C.cgroup_strerror(C.ECGEOF)))
// End-of-file for iterators
ECGEOF = errors.New(C.GoString(C.cgroup_strerror(C.ECGEOF)))
ECGOTHER = errors.New(C.GoString(C.cgroup_strerror(C.ECGOTHER)))
)
/*
* Return last errno, which caused ECGOTHER error.
*/
func LastError() error {
return _err(C.cgroup_get_last_errno())
}
func _err(num C.int) error {
switch num {
case 0:
return nil
case C.ECGEOF:
return ECGEOF
case C.ECGOTHER:
return ECGOTHER
}
// There's a lot. We'll create them as they come
return errors.New(C.GoString(C.cgroup_strerror(num)))
}
func Init() error {
return _err(C.cgroup_init())
}