How to use cgroup to limit resource for ssh session

/etc/profile and /etc/profile.d

Before we discuss how to limit process resource usage with cgroup for ssh session, let’s take a moment to know about /etc/profile and /etc/profile.d in Linux.

/etc/profile

This is the system-wide profile file, which will be executed, when a user logs in to the shell environment.

$ cat /etc/profile
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).

if [ "${PS1-}" ]; then
  if [ "${BASH-}" ] && [ "$BASH" != "/bin/sh" ]; then
    # The file bash.bashrc already sets the default PS1.
    # PS1='\h:\w\$ '
    if [ -f /etc/bash.bashrc ]; then
      . /etc/bash.bashrc
    fi
  else
    if [ "$(id -u)" -eq 0 ]; then
      PS1='# '
    else
      PS1='$ '
    fi
  fi
fi

if [ -d /etc/profile.d ]; then
  for i in /etc/profile.d/*.sh; do
    if [ -r $i ]; then
      . $i
    fi
  done
  unset i
fi

/etc/profile.d

Files in /etc/profile.d/ are run when a user logs in (unless you’ve modified /etc/profile above to not do this) and are generally used to set environment variables.

Depending on which distribution of Linux you are using, you will find a variety of files in this directory.

$ ls -ltr /etc/profile.d/
total 92
-rw-r--r--  1 root root  379 Jun 13  2012 qt-graphicssystem.sh
-rw-r--r--  1 root root  313 Jun 29  2012 qt-graphicssystem.csh
-rw-r--r--. 1 root root  169 Jan 27  2014 which2.sh
-rw-r--r--. 1 root root  164 Jan 27  2014 which2.csh
-rw-r--r--. 1 root root  121 Jul 30  2015 less.sh
-rw-r--r--. 1 root root  123 Jul 30  2015 less.csh
-rw-r--r--. 1 root root  201 Mar 24  2017 colorgrep.sh
-rw-r--r--. 1 root root  196 Mar 24  2017 colorgrep.csh
-rw-r--r--. 1 root root 1606 Aug  6  2019 colorls.sh
-rw-r--r--. 1 root root 1741 Aug  6  2019 colorls.csh
-rw-r--r--. 1 root root  660 Apr  1  2020 bash_completion.sh
-rw-r--r--. 1 root root   81 Apr  1  2020 sh.local
-rw-r--r--. 1 root root   80 Apr  1  2020 csh.local
-rw-r--r--. 1 root root 1348 Oct  1  2020 abrt-console-notification.sh
-rw-r--r--. 1 root root 2703 Oct 13  2020 lang.sh
-rw-r--r--. 1 root root 1706 Oct 13  2020 lang.csh
-rw-r--r--. 1 root root  841 Oct 13  2020 256term.sh
-rw-r--r--. 1 root root  771 Oct 13  2020 256term.csh
-rw-r--r--  1 root root  269 Dec 15  2020 vim.sh
-rw-r--r--  1 root root  105 Dec 15  2020 vim.csh
-r--r--r--  1 root root   31 Apr  4  2022 99bash_history.sh
-r-xr-xr-x  1 root root  948 Apr  4  2022 99remote_user_info.sh
-r-xr-xr-x  1 root root  551 Apr  4  2022 99bash_logging.sh
lrwxrwxrwx  1 root root   39 Apr  4  2022 90-updates-available.sh -> /etc/update-motd.d/90-updates-available

Create ssh profile under /etc/profile.d for cgroup resource limit

In this example, we want to limit the IO bandwidth for the ssd sessions logs in the system.

To achieve this, we create a ssh.sh profile as below.

$ cat ssh.sh
# log a ssh session date
date > /root/ssh.log

# set resource limit
/root/config_cgroup_io.sh >> /root/ssh.log  

# limit reource for all the processes of current ssh session
echo $$ > /sys/fs/cgroup/blkio/cgroup.procs 

Move the ssh profile to /etc/profile.d so that it will be executed automatically for future ssh login.

$ mv ssh.sh /etc/profile.d/

The following is an example script to limit r/s and w/s for the device “259:2” to 8000 with cgroup.

$ cat config_cgroup_io.sh
iops=8000
bps=`expr 50 \* 1024 \* 1024` # bytes per second
major=259
minor=2

echo "$major:$minor  $iops" > /sys/fs/cgroup/blkio/blkio.throttle.write_iops_device
echo "$major:$minor  $iops" > /sys/fs/cgroup/blkio/blkio.throttle.read_iops_device

At this point, we have setup a way to limit ssh session resource usage with cgroup. Hope this is helpful.