Added new package icgroupd, refs #2521

The icgroupd contains a simple shell script daemon and an procd enabled init script
for configuring cgroups according to uci configuration and launching the daemon.

The daemon will periodically look for new processes in the root cgroup and move
them to sub-groups according to configuration.
This commit is contained in:
Mats Karrman 2016-04-15 11:41:10 +02:00
parent 482a88a65b
commit 8f63a74197
4 changed files with 263 additions and 0 deletions

46
icgroupd/Makefile Normal file
View file

@ -0,0 +1,46 @@
#
# Copyright (C) 2016 Inteno Broadband AB
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=icgroupd
PKG_VERSION:=1.0
PKG_RELEASE:=0
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=
PKG_MAINTAINER:=Inteno Broadband AB
include $(INCLUDE_DIR)/package.mk
define Package/icgroupd
SECTION:=base
CATEGORY:=Base system
TITLE:=Inteno cgroup daemon
DEPENDS:=+uci +busybox
endef
define Package/icgroupd/description
This package contains Intenos cgroup daemon and associated
configuration and startup scripts.
endef
define Build/Compile
true
endef
define Package/icgroupd/install
$(INSTALL_DIR) $(1)/sbin $(1)/etc/init.d $(1)/etc/config
$(INSTALL_CONF) ./files/cgroups.config $(1)/etc/config/cgroups
$(INSTALL_BIN) ./files/cgroups.init $(1)/etc/init.d/cgroups
$(INSTALL_BIN) ./files/cgroupd $(1)/sbin/
endef
$(eval $(call BuildPackage,icgroupd))

76
icgroupd/files/cgroupd Executable file
View file

@ -0,0 +1,76 @@
#!/bin/sh
CGBASEDIR=$1
CGCONFIG=$2
[ -n "$CGBASEDIR" -a -n "$CGCONFIG" ] || exit 1
[ -r /lib/functions.sh ] || exit 1
. /lib/functions.sh
CGPROCMAP=/tmp/cgprocmap
CGPERIOD=3s
DBGLOG=/tmp/cgroupd.log
DEBUG=0
add_to_procmap () {
local name_grp=$1
local name grp
name=$(echo $name_grp |awk -F= '{print $1}')
grp=$(echo $name_grp |awk -F= '{print $2}')
echo "($name) $grp" >> $CGPROCMAP
}
# Read configuration file and create process:group look-up table
# in /tmp file
read_config () {
local enab
config_load $CGCONFIG
config_get enab cgroups enabled "1"
[ $enab -eq 0 ] && exit 1
config_get CGDEFGROUP cgroups defgroup "_undef_"
[ "$CGDEFGROUP" == "_undef_" ] && exit 1
[ "$DEBUG" == "1" ] && echo "default $CGDEFGROUP" >> $DBGLOG
echo -n '' > $CGPROCMAP
config_list_foreach procmap procmap add_to_procmap
[ "$DEBUG" == "1" ] && cat $CGPROCMAP >> $DBGLOG
}
# Move all process except init from cgroup root to cgroups according
# to /tmp look-up table
move_wild_procs () {
local wild_procs=$(cat $CGBASEDIR/cgroup.procs)
local pid name grp
for pid in $wild_procs; do
[ $pid -eq 1 ] && continue
if [ -d /proc/$pid ]; then
name=$(awk '{print $2}' /proc/$pid/stat)
grp=$(awk "\$1==\"$name\" {print \$2}" $CGPROCMAP)
[ "$grp" == "." ] && continue
[ -n "$grp" ] || grp=$CGDEFGROUP
[ "$DEBUG" == "1" ] && \
echo "Moving proc $pid $name to $grp" >> $DBGLOG
echo $pid > $CGBASEDIR/$grp/cgroup.procs
fi
done
}
[ "$DEBUG" == "1" ] && echo "$0 started $(date)" >> $DBGLOG
read_config
while true; do
move_wild_procs
sleep $CGPERIOD
done

View file

@ -0,0 +1,48 @@
config cgroups cgroups
option enabled 1
option defgroup iopsys/normal
config cgroup _root_
list option cpu.rt_runtime_us=50000
list option memory.move_charge_at_immigrate=1
config cgroup iopsys
list option cpu.shares=4096
list option cpu.rt_runtime_us=40000
list option memory.limit_in_bytes=-1
list option memory.move_charge_at_immigrate=1
config cgroup iopsys_normal
list option cpu.shares=1024
list option cpu.rt_runtime_us=10000
list option memory.limit_in_bytes=-1
list option memory.move_charge_at_immigrate=1
config cgroup iopsys_high
list option cpu.shares=4096
list option cpu.rt_runtime_us=30000
list option memory.limit_in_bytes=-1
list option memory.move_charge_at_immigrate=1
config cgroup 3prt
list option cpu.shares=1024
list option cpu.rt_runtime_us=10000
list option memory.limit_in_bytes=75M
list option memory.move_charge_at_immigrate=1
config cgroup 3prt_normal
list option cpu.shares=1024
list option cpu.rt_runtime_us=2500
list option memory.limit_in_bytes=75M
list option memory.move_charge_at_immigrate=1
config cgroup 3prt_high
list option cpu.shares=4096
list option cpu.rt_runtime_us=7500
list option memory.limit_in_bytes=75M
list option memory.move_charge_at_immigrate=1
config procmap procmap
list procmap kthreadd=.
list procmap minidlna=3prt/normal

93
icgroupd/files/cgroups.init Executable file
View file

@ -0,0 +1,93 @@
#!/bin/sh /etc/rc.common
START=01
USE_PROCD=1
PROCD_DEBUG=1
NAME=cgroupd
CGBASEDIR=/sys/fs/cgroup
CGCONFIG="cgroups"
DBGLOG=/tmp/cginit.log
DEBUG=0
cgroupinit_set_knob_value () {
local knob_val=$1
local dir=$2
local knob val
knob=$(echo $knob_val |awk -F= '{print $1}')
val=$(echo $knob_val |awk -F= '{print $2}')
/bin/echo $val > $CGBASEDIR/$dir/$knob
[ "$DEBUG" == "1" ] && \
echo "/bin/echo $val > $CGBASEDIR/$dir/$knob (ret=$?)" >> $DBGLOG
}
cgroupinit_create_group () {
local cgrp=$1
local dir
[ "$DEBUG" == "1" ] && echo "Create group $cgrp:" >> $DBGLOG
if [ "$cgrp" == "_root_" ]; then
dir=.
else
dir=$(echo $cgrp |tr '_' '/')
if [ ! -d $CGBASEDIR/$dir ]; then
mkdir $CGBASEDIR/$dir
[ "$DEBUG" == "1" ] && \
echo "mkdir $CGBASEDIR/$dir (ret=$?)" >> $DBGLOG
fi
fi
config_list_foreach $cgrp option cgroupinit_set_knob_value $dir
}
cgroupinit_configure_cgroups () {
local enab defgrp
[ "$DEBUG" == "1" ] && echo "$0 started $(date)" >> $DBGLOG
config_load $CGCONFIG
config_get enab cgroups enabled "1"
[ $enab -eq 0 ] && return 1
config_get defgrp cgroups defgroup "_undef_"
[ "$defgrp" == "_undef_" ] && return 1
if ! grep -q " $CGBASEDIR cgroup " /proc/mounts; then
mount -t cgroup -o nodev,noexec,nosuid cgroup $CGBASEDIR
[ $? -eq 0 ] || return 1
fi
config_foreach cgroupinit_create_group cgroup
return 0
}
start_service () {
cgroupinit_configure_cgroups
[ $? -eq 0 ] || return
procd_open_instance
procd_set_param command /sbin/cgroupd $CGBASEDIR $CGCONFIG
procd_set_param respawn
procd_close_instance
}
stop_service () {
local cgdir procs prc
for cgdir in $(find $CGBASEDIR -type d -mindepth 1 -depth); do
procs=$(cat $cgdir/cgroup.procs)
for prc in $procs; do
echo $prc > $CGBASEDIR/cgroup.procs
done
rmdir $cgdir
done
}
service_triggers() {
procd_add_reload_trigger $CGCONFIG
}