
----------------------------------------------------------------------
Resource Control Lists (RCLs)
----------------------------------------------------------------------

This is a snapshot of Resource Control List implementation. 
It is still undergoing development.

1. Introduction to Resource Control Lists and some background.

RCLs specify and enforce protection policies on time-multiplexed
resources such as CPU time or network bandwidth, similar to access
control on files.  RCLs are specifications that describe who (resource
principal) is allowed to get what and how much.  Effectively, RCLs
describe the policy which the system abides by.

RCLs allows one to specify policy based on resource principals rather
than processes. A resource principal is an entity to which resource
usage can be charged.  The recognition that it was often inadequate to
charge resource usage to processes (in UNIX terminology), led to the
concept of resource principals.  This made it possible to charge
resources based on activities. An activity denotes a unit of
computation for which the application or the system wishes to perform
separate resource allocation and accounting; for example, the
processing associated with a single HTTP request is considered a
single activity. Thus, all entities involved in this activity is
considered a member of a single resource principal.  An activity can
span multiple protection domains.  Also, by using RCLs, one can attach
reservation to unmodified "legacy" applications that runs on Linux.

Another feature supported is resource propagation.  That is, the
reservation of the sender is propagated to the receiver. For example,
a shared server may want to inherit reservation from its clients (=
propagation).  When a client requests a server for service (through a
communication channel such as IPC), the server works on behalf of that
specific client. But when a server is serving another client, it is
working on behalf of a different client. Thus, the reservation used by
that server should reflect the client it is serving at that
time. Hence, clients will propagate its reservation dynamically as it
makes its requests.  This feature enables the dynamic changes of
reservation based on communication requests.



2. Configuration of RCLs

Support for RCL is implemented as kernel module, filter.o . Filter.o
depends on rk.o (which implements the RK feature) being loaded.
Currently the configuration for RCL is embedded in the source code.
We plan to make this into a configuration file in the future.  The
main configuration structure is located in rcl_manager.c and
socketfilter.c


2.1 rcl_manager.c

To configure RCL, you need to modify the structure resource_control.
In the future, we will make this into a configuration file that the
module reads in when loaded. The definition of struct resource_control
is described in rclmodule.h. Basically, you need to specify,

	name:  		name of the entry
	linenumber:  	line number in RCL list (probably will become obsolete)
	version:     	we used to have several version of RCLs specified. I have not
			tested this feature lately.
	uid:	     	user id used as attribute of resource principal 
	saddrip:	source IP address as attribute of resource principal 
			eg) if you want to treat packets from certain IP as 
			one entity (resource principal)
	progname:	program name as attribute of resource principal 
			(you cannot specify IP addr and progname in the same entry)
	inherit:	parental control (if set, all child process will be included in the 
			same resource principal)
	use_reserv:	RESERV or NORESERV
	ct, tt:		attributes for reservation 
			eg) C (computation time) and T (period)	
	p:		type of reservation
	nect, rpal:	specify 0 and NULL (will be initialized by module)


For example, if you want to attach 'make' and all the programs spawned
by 'make' (eg. gcc, cpp, ld, ar...) with user id 0 (root) with CPU
reservation of 150ms computation time with 1000ms period (15%), an
entry may look like this.

"RCL-1" ,0, RCL0, 0, "", "/usr/bin/gcc", 
INHERIT , RESERV,
{0, 150*1000*1000}, {0,1000*1000*1000}, {RSV_HARD,RSV_HARD,RSV_HARD},  0, NULL}, 

If you want to attach CPU reservation of 10% to all other 'make'
processes that was spawned by all other user id, after the previous
line, you would specify some thing like this:

"RCL-1" ,0, RCL0, -1, "", "/usr/bin/gcc", 
INHERIT , RESERV,
{0, 100*1000*1000}, {0,1000*1000*1000}, {RSV_HARD,RSV_HARD,RSV_HARD},  0, NULL}, 

Note that wild card in the user id is represented by the -1 value. And
the ordering of the entry is very important. The system will use the
first matching entry. Thus, if root (user id 0) execute a make
program, the first entry with 15% of CPU reservation will match. All
other make process will receive a combined amount of 10% which is
specified after the first reservation with 15%.

An entry in this structure will attach the resource principal
(specified by uid, progname or the IP address) to the reservation
specified. As illustrated in the "default" resource principal,
multiple processes matching an single RCL entry can belong to the same
resource principal and treated as a single entity.


2.2 socketfilter.c

To configure the resource propagation feature, you need to modify
struct sock_access_control in socketfilter.c.  Currently you specify
the program name of the party you are interested in, instead of the
resource principal itself. This should be fixed soon. The structure
sock_access_control is defined in socketfilter.h.

version:		obsolete
srv_progname: 		the program name of the server
cli_progname:		the program name of the client
srv_pid, cli_pid:	specify -1 and -1. System will initialize this value.

Note that before you use resource propagation, you need to attach
reservation to the client at rcl_manager.c.


3. Misc Info

You need to load the module BEFORE any program you are going to use is
started. Or else you will risk inaccurate enforcement or worse, the
system crashing.  For example, if you plan to use any program that
uses the X server (eg. xterm), you need to load filter.o BEFORE you
start X. Note that there are many programs that you may be using
without realizing it. For example daemon programs such as the syslogd.
What I do recommend is to load the rk.o module and filter.o module at
system startup time (somewhere in the rc scripts).


4. Testing RCLs

One of the features of RCLs is that you don't need to modify your
legacy applications in order to benefit from resource reservations.
Here we show some simple ways to use RCLs.

4.1 Useful tools

There are several useful tools to see if RCL is doing what it is
supposed to do. 'rklist' and 'procrkmonitor' which comes with the
distribution of RK is one of such utilities.  For example, rcl_manager.c
has an entry for /usr/bin/make which says it will get 15% CPU if
spawned by root and 10% CPU if spawned by somebody else .  Try to
"make" something (like the kernel) and see how much reservation make
and all it's children (gcc, cpp, ld, ar,...etc) is using by using
procrkmonitor. You can also visually see that your 'make' is taking
alot of time since you are running on a CPU only 15% or 10% of the original
capacity.

4.2 Containing the Effect of Intruder Resource Usage

Lets say you are the primary user of some shared machine. You notice
that other people are using more resources that you want them and you
are not getting enough resources. You can configure RCLs so that all
resources used by programs that originally come from remote entry
points (telnet, ftp) are contained.

For example, currently resource control list set in
rcl_manger.c has an entry which says:

  {"RCL-3", 2, RCL0, -1, "128.2.220.93", "", 
   INHERIT , RESERV,
   {0, 3*1000*1000}, {0,30*1000*1000}, {RSV_HARD,RSV_HARD,RSV_HARD},  0, NULL},

This means that all activities that originate from 128.2.220.93 will
be contained to 10% (c=3ms, t=30ms) of CPU. Note that the INHERIT flag
is set. To see how this can be used, start your favorite real-time
continuous media application (eg. movie player mpeg_play). Modify the
IP address "128.2.220.93" to an remote machine you have access to
(lets call this host X).  Load rk module and filter module.  Telnet
into your machine from host X.  In this current directory we have put
a simple "whileloop" program.  Spawn off as many whileloop programs as
you like (eg. %./whileloop & ; ./whileloop & ; ./whileloop & ;
./whileloop & ) from the terminal you have entered into from host X.
You will see that mpeg_play's frame-rate will remain constant. Now
try to do the same thing WITHOUT loading RCLs.  If you spawn off many
whileloops you will surely see a degradation in the framerate of your
movie player application.

What has happened is that, when you telnet into your machine from host
X, RCL will attach a reservation to the remote entry point. And from
that entry point on, all the child process spawned off such as login,
tcsh, whileloop (See Figure 1.) will INHERIT the reservation. Thus,
whatever you do from the terminal of host X, it will be contained in
the same reservation.


 |-inetd(345)-+-in.telnetd(801)---login(802)---tcsh(803)-+-whileloop(981)
        |            |                                          `-whileloop(982)

	Figure 1. Child spawned off from remote entry point



* Note that there is a bug in the software where sometimes it won't
create a reservation at the first try. (Once you get it to work, it
will work continuously) Try to see if reservation has been created
using 'rklist' program when you login from host X. If not try to login
from your host to host X or the other way around. That should trigger
the creation of reservation.  Or ping host X from your machine (and
vice versa). Once the reservation is created than it should work
correctly. 

* If you do not have a sleep in the whileloop, you probably won't get
back your terminal for a long time if ever :-)


4.3 Resource Propagation

There are three programs in this directory you can use to see how
resource propagation works. server-select, client-select, and
client-select2.  server-select is a server and client-select and
client-select communicate with the server via IPC. client-select and
client-select2 are actually the same program but with different names.

If you observe rcl_manger.c and socketfilter.c, it is set to propagate
the reservation of program client-select to server-select when the two
communicate. (Note that absolute paths are used in the configuration.)
And client-select has a reservation of 80%.  

server-select takes two arguments. Number of clients and total number of IPC.
(Each client requests 20 IPC to server.) 

terminal1 % /usr/home/miyos/W/RK/LinuxRK/LinuxRK/RCL/server-select 1 20    
terminal2 % /usr/home/miyos/W/RK/LinuxRK/LinuxRK/RCL/client-select

client-select program should return the response time of the server.
Now try something like this,

terminal1 % /usr/home/miyos/W/RK/LinuxRK/LinuxRK/RCL/server-select 4 80    
terminal2 % /usr/home/miyos/W/RK/LinuxRK/LinuxRK/RCL/client-select
terminal3 % /usr/home/miyos/W/RK/LinuxRK/LinuxRK/RCL/client-select2 &
terminal3 % /usr/home/miyos/W/RK/LinuxRK/LinuxRK/RCL/client-select2 &
terminal3 % /usr/home/miyos/W/RK/LinuxRK/LinuxRK/RCL/client-select2 &

Make sure you start client-select before client-select2. This is
because server-select puts preference in the first socket using
select() system call.  Now turn off resource propagation and repeat the
same experiment.  You should see a big difference in response time for
client-select.  This shows that attaching reservation only to
client-select is not enough and resource propagation is needed.

EOF


