11

I want to create some control groups using cgroup.

So far I have done the following:

  1. I installed some packages:

    sudo apt-get install cgroup-bin cgroup-lite cgroup-tools cgroupfs-mount libcgroup1
    
  2. Then I created the /etc/cgconfig.conf file with the following content:

    mount {
      cpuset  = /cgroup/cpuset;
      cpu     = /cgroup/cpu;
      cpuacct = /cgroup/cpuacct;
      memory  = /cgroup/memory;
      devices = /cgroup/devices;
      freezer = /cgroup/freezer;
      net_cls = /cgroup/net_cls;
      ns      = /cgroup/ns;
      blkio   = /cgroup/blkio;
    }
    
    group limitcpu{
      cpu {
        cpu.shares = 400;
      }
    }
    
    group limitmem{
      memory {
        memory.limit_in_bytes = 512m;
      }
    }
    
    group limitio{
      blkio {
        blkio.throttle.read_bps_device = "252:0         2097152";
      }
    }
    
    group browsers{
      cpu {
        cpu.shares = 200;
      }
      memory {
        memory.limit_in_bytes = 128m;
      }
    }
    

    according to the guide here, assuming, that the config file resides at the same location and uses the same syntax on Ubuntu, as it uses on CentOS.

  3. Then according to that guide I need to start the cgconfig service. I tried with:

    sudo service cgconfig restart
    

    But, oh no! A file is missing!:

    Failed to restart cgconfig.service: Unit cgconfig.service not found.
    
  4. After some wondering and searching around, I tried:

    ● cgconfig.service
       Loaded: not-found (Reason: No such file or directory)
       Active: inactive (dead)
    

So it seems I am simply not having any cgconfig service on my system!

I searched for it using:

sudo aptitude search cgconfig

However, no cgconfig is to be found.

How can I install cgconfig on my Ubuntu 16.04?

13

OK, I managed myself to do the same you did, but with some changes:

1) I installed the same utilities:

sudo apt-get install cgroup-bin cgroup-lite cgroup-tools cgroupfs-mount libcgroup1

2) I edited conf files like this:

/etc/init/cgroup-lite.conf

description "mount available cgroup filesystems"
author "Serge Hallyn <serge.hallyn@canonical.com>"

start on mounted MOUNTPOINT=/sys/fs/cgroup

pre-start script
test -x /bin/cgroups-mount || { stop; exit 0; }
test -d /sys/fs/cgroup || { stop; exit 0; }
/bin/cgroups-mount
cgconfigparser -l /etc/cgconfig.conf
end script

post-stop script
if [ -x /bin/cgroups-umount ]
then
    /bin/cgroups-umount
fi
end script

/etc/cgconfig.conf

# Since systemd is working well, this section may not be necessary.
# Uncomment if you need it
#
# mount {
# cpuacct = /cgroup/cpuacct;
# memory = /cgroup/memory;
# devices = /cgroup/devices;
# freezer = /cgroup/freezer;
# net_cls = /cgroup/net_cls;
# blkio = /cgroup/blkio;
# cpuset = /cgroup/cpuset;
# cpu = /cgroup/cpu;
# }

group limitcpu{
  cpu {
    cpu.shares = 400;
  }
}

group limitmem{
  memory {
    memory.limit_in_bytes = 512m;
  }
}

group limitio{
  blkio {
    blkio.throttle.read_bps_device = "252:0         2097152";
  }
}

group browsers {
    cpu {
#       Set the relative share of CPU resources equal to 25%
    cpu.shares = "256";
}
memory {
#       Allocate at most 512M of memory to tasks
        memory.limit_in_bytes = "512m";
#       Apply a soft limit of 512 MB to tasks
        memory.soft_limit_in_bytes = "384m";
    }
}

group media-players {
    cpu {
#       Set the relative share of CPU resources equal to 25%
        cpu.shares = "256";
    }
    memory {
#       Allocate at most 256M of memory to tasks
        memory.limit_in_bytes = "256m";
#       Apply a soft limit of 196 MB to tasks
        memory.soft_limit_in_bytes = "128m";
    }
}

cgconfigparser -l /etc/cgconfig.conf

And /etc/cgrules.conf

user:process                                         subsystems   group
[user]:/usr/lib/chromium-browser/chromium-browser   cpu,memory      browsers
[user]:/usr/bin/clementine                        cpu,memory     media-players

That is an example, use your username instead of [user]. You can add the applications you need to limit and define whether you want them to be CPU-, memory- or both limited.

I edited the GRUB_CMDLINE_LINUX_DEFAULT line in /etc/default/grub:

GRUB_CMDLINE_LINUX_DEFAULT="cgroup_enable=memory swapaccount=1"

Updating it:

sudo update-grub

3) And finally rebooting to apply changes.

And that is how I've got this working. Before this I was having frequent OOMs with multitasking - with chromium-browser, clementine, sublime-text and other applications using a lot of resources -, now they are running smoothly and I can multitask better.

I really hope this may help others.

Currently using Ubuntu 16.04 LTS with Intel Dual Core 2.6 Ghz and 4 Gb. RAM.

  • 1
    This feels like the right approach, but instead of using cgrules.conf, I find cgexec to be better. Also, I think you meant to name the file cgconfig.conf and not cgconf.conf. If systemd is doing its job, I don't think you need the mount section in this file. – Mark Apr 18 '17 at 16:48
  • I edited this reply following Mark's recommendation, tested it and works well. – Rdrk Apr 22 '17 at 4:28
  • @Mark, I would be interested in your solution with cgexec. – Jonathan Jul 26 '17 at 14:11
7

I faced the same issue. It looks like there is no built-in service in current Ubuntu distributions to load cgroup config files.

You will find some (broken?) example init scripts at /usr/share/doc/cgroup-tools/examples/cgconfig and /usr/share/doc/cgroup-tools/examples/cgred.

To manually load the config files you can use

# Loads /etc/cgconfig.conf 
cgconfigparser -l /etc/cgconfig.conf

# Loads /etc/cgrules.conf
cgrulesengd -vvv --logfile=/var/log/cgrulesengd.log

As a poor man's solution I wrote myself an init script that loads both files on system startup.

#!/bin/sh
### BEGIN INIT INFO
# Provides:          cgconf
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Should-Start:
# Should-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Configures CGroups
### END INIT INFO

start_service() {
  if is_running; then
    echo "cgrulesengd is running already!"
    return 1
  else
    echo "Processing /etc/cgconfig.conf..."
    cgconfigparser -l /etc/cgconfig.conf
    echo "Processing /etc/cgrules.conf..."
    cgrulesengd -vvv --logfile=/var/log/cgrulesengd.log
    return 0
  fi
}

stop_service() {
  if is_running; then
    echo "Stopping cgrulesengd..."
    pkill cgrulesengd
  else
    echo "cgrulesengd is not running!"
    return 1
  fi
}

status() {
  if pgrep cgrulesengd > /dev/null; then
    echo "cgrulesengd is running"
    return 0
  else
    echo "cgrulesengd is not running!"
    return 3
  fi
}

is_running() {
  status >/dev/null 2>&1
}

case "${1:-}" in
  start)
    start_service
    ;;
  stop)
    stop_service
    ;;
  status)
    status
    ;;
  *)
    echo "Usage: /etc/init.d/cgconf {start|stop|restart|status}"
    exit 2
    ;;
esac

exit $?

Save this file at /etc/init.d/cgconf and install it using

# make the script executable
chmod 755 /etc/init.d/cgconf

# register the service
update-rc.d cgconf defaults

# start the service
service cgconf start

# check the status
service cgconf status

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.