Design
========

After cgroup system has taken shape, its time to have some basic tools
in user space which can enable a user to use the resource management
functionality effectively.

One of the needed functionality is rule based placement of a task.  In general,
there can be either uid or gid or exec based rules. Admin/root will
control/enforce uid/gid based rules and exec based rules can be defined by
user in a config file residing in user's home dir and fully controlled by user.

uid/gid based rules will be defined in /etc/cgrules.conf config file and
this file will be managed by root.

Basic idea is that to begin with provide facility to implement rules
based on uid and gid. So a hierarchy might look like as follows.

                        /sys/fs/cgroup
                        |       |
                      gid1      gid2
                     |   |
                   uid1 uid2
                  |   |
               proj1  proj2


Admin will write rules to control the resources among users. Then users
can manage their own cgroup at their own (proj1 and proj2) and control
the resources as they want.

Following are the few methods using which tasks can be placed in right
cgroups.

- Use pam_cgroup PAM plugin which will make sure users are placed in right
  cgroup at login time and any tasks launch after login, will continue to run
  in user's cgroup.

- Use command line tool "cgexec" to launch the task in right cgroup.

- Modify the program and use libcgroup provided APIs for placing a task
  in right cgroup before doing exec().

- Use "cgclassify" tool to classify a already running task.

- May be, a user space daemon can also be implemented which will listen to
  kernel events and place the task in right group based on the rules.
  This method involves few concerns.

	- Reliability of netlink socket. Messages can be dropped.
		- Change the netlink with a cgroup controller which exports the
	  	  events.

	- Delay incurred since the event took place and task was actually placed
  	  in right cgroup.

	- daemon will interfere with container's tasks which is not desired.

HOWTO
=====

Section 1:
----------
To use "cgexec" to place the task in right cgroup.

- make cgexec
- Run a task using cgexec. Following is the cgexec syntax.

 cgexec [-g <list of controllers>:<relative path to cgroup>] command [arguments]

 Note: Cgroup controllers and path are optional. If user does not know the
       right cgroup, cgexec will automatically place the task in right
       cgroup based on /etc/cgrules.conf

Example:
	cgexec -g *:test1 ls
	cgexec -g cpu,memory:test1 ls -l
	cgexec -g cpu,memory:test1 -g swap:test2 ls -l

Section 2
---------
To use "cgclassify" to place task in right cgroup.

- make cgclassify
- Pick a task's pid to be classified, and run
	cgclassify <list of pids>

Example:
--------
	cgclassify 2140 4325

	Note: After classification check out whether tasks 2140 and 4325
	are in the right cgroup or not (Based on rules in /etc/cgrules.conf)

Section 3:
----------
To use a pam plugin which will automatically place the task in right
cgroup upon login.

- Build pam_cgroup.so
	make pam_cgroup.so
- Copy pam_cgroup.so to /lib/security/
- Edit /etc/pam.d/su to make use of pam_cgroup.so session module upon
  execution of su.

example:
	Add following line at the end of /etc/pam.d/su file

session                optional        pam_cgroup.so

- Now launch a shell for a user "xyz" using su and the resulting shell
  should be running in the cgroup designated for the user as specified
  by cgrules.conf

  ex. "su test1"

Try similar things with other services like sshd.

Note: pam_cgroup.so moves the service providing process in the right cgroup
      and not the process which will be launched later. Due to parent child
      relationship, yet to be forked/execed process will launch in right
      group.

Ex. Lets say user root does "su test1". In this case process "su" is the
    one providing service (launching a shell) for user "test1". pam_cgroup.so
    will move process "su" to the user "test1"'s cgroup (Decided by the uid
    and gid of "test1"). Now once su forks/execs a shell for user test1,
    final shell is effectively running in the cgroup it should have been
    running based on /etc/cgrules.conf for user test1.


Section 4:
----------
To use cgrulesengd which will move a task to right cgroup based on
rules in /etc/cgrules.conf do following.

- build and install latest libcgroup.so
- build cgrulesengd
	make cgrulesengd
- specify some uid/gid based rules in /etc/cgrules.conf
- Mount some controllers and create an hierarchy of cgroups (matching
  your rules).
- Run cgrulesengd.
	- ./cgrulesengd
- Launch some task or login as a user to the system. Daemon should automatically
  place the task in right cgroup.

FAQ
===
Q. Why admin should not control "exec" based rules.
A. Unix file system provides access control only based on uid/gid. So
   even if admin starts putting tasks based on uid/gid, it can't enforce
   it. For example, consider following scenario.

  Lets say an admin creates following cgroup hierarchy.

			/container
			|	|
  		database	browser
		|    |		|     |
	      user1  user2     user1  user2

 Now admin wants to run all the database jobs under /container/database/
 and all the firefox jobs under /container/browser/. Based on which user
 launched it, jobs should go in either user1 or user2 dir.

 Now assume that database subdir has to more cpu resources as compared to
 browser subdir. Then a user, say user2, can always move his browser job
 also to /container/database/user2 dir to get more cpu resources and
 admin will not be able to control that.

 [Note: user2 will control what tasks can be added in /container/database/user2
  and will control what further subdirs can be created under user2 dir. Root
  should not restrict the control to root only for practical purposes. Its
  something like that till /container/database, admin controls the resources
  and below that how resources are further subdivided among various projects
  should be controlled by respective user].

In the light of above, it seems to make more sense that admin should enforce
rules only based on uid and gid. Probably later we can have a per user exec
based rules config file (~/.cgrules.conf), which can be parsed by cgrulesengd
and then jobs launched by user will be placed in right cgroup based on
combination of rules in /etc/cgrules.conf and ~/cgrules.conf.
