Solaris Resource Manager

Solaris Resource Manager

Resource Management is an rather old feature in Solaris, albeit it got more mind share since it got a really important part of the Solaris Zones. But this tutorial doesn’t focus on the usage of Resource Management in conjunction with the zone configuration. I want to go to the basics, because at the end the zone configuration just uses this facilities to control the resource consumption of zones. Secondly you can use this knowledge to limit resource usage in a zone itself.

Resource Management was introduced to solve one important question. You can run multiple programs and services at once in a single instance of the operating system, but how do I limit the consumption of resources of a single application? How do I prevent a single program from consuming all the resources leaving nothing to others? Resource Management in Solaris solves this class of problems.

Why do you need Resource Management?

Unix systems were capable to execute a multitude of independent services on one system since its introduction many years ago. But there was a problem: What happens in case of a process running amok? A user eating away resources of the system? You have to control the allocation of this resources. How many CPU does a process get? How many file descriptors are allocated to a user? The Solaris Resource Management is capable to put other processes under the control of an user configurable ruleset. Thus you can prevent a situation where your system is down, because a single process takes all resources.

With such an ability, the usage of a single system for a multitude of services becomes more manageable and thus more feasible.

Definitions

Okay, as usual, this technology has its own jargon. So I have to define some of it at first:

  • Tasks: A task is a group of processes. For example when you log into a system and do some work all the steps you’ve done are an task until you logout or open a new task. Another example would be a webserver. It consists out of a multitude of processes, but they are all part of the same task. The database server on the same machine may have a completely different task id.

  • Projects: A project is a group of tasks. For example you have a webserver. It consists out of the processes of the database task and the webserver task.

  • Zones: From the perspective of the resource management, a Solaris Zone is just a group of one or more projects.

The basic idea of Solaris Resource Management

The basic idea of resource management is to use the grouping of processes and to impose limits on a group on processes defined by one of the above entities. A limit on the zone would limit all projects in a zone. A limit on the project would limit all tasks grouped by the project. A limit on a task would limit all processes grouped by the tasks.

Let’s take an example: There is a resource control called max-lwps. It controls the amount of processes. This control exists as task.max-lwps, project.max-lwps and zone.max-lwps. With this control you can define limits for the number of processes in a group of processes defined by one of the entities mentioned above.

You want to ensure, that you have 1000 processes at maximum in your zone webserver. You can define it by using zone.max-lwps for the zone webserver. You want to ensure, that the www.c0t0d0s0.org webserver project consisting out of mysql and apache processes uses 250 processes at maximum. You use the project.max-lwps for the project webserver-c0t0d0s0. You want to limit the httpd-server itself to 100 processes. You impose this limit by using the task.max-lwps control.

How do you configure this? This will be the topic of this tutorial. It sounds complex, but it isn’t, once you’ve understand the entities.

How to work with projects and tasks

Even when you never heard of constructs like tasks and projects you already use them, as there are a few projects installed per default. For example whenever you log into your system as a regular user, all you do is part of the project default because your user is member of this project:

# su jmoekamp
# id -p
uid=100(jmoekamp) gid=1(other) projid=3(default)

When you assume the privileges of the root user you work as a member of the user.root project.

$ su root
Password: 
# id -p
uid=0(root) gid=0(root) projid=1(user.root)

Let’s have another look at the alread running processes of your system.

# ps -ef -o pid,user,zone,project,taskid,args
  PID     USER     ZONE  PROJECT TASKID COMMAND
    0     root   global   system     0 sched
[...]
  126   daemon   global   system    22 /usr/lib/crypto/kcfd
  646 jmoekamp   global  default    73 /usr/lib/ssh/sshd
[...]
  413     root   global user.root    72 -sh
  647 jmoekamp   global  default    73 -sh
[...] 
  655     root   global user.root    74 ps -ef -o pid,user,zone,project,taskid,args
  651     root   global user.root    74 sh

As you see from the output of ps you already use some projects, that are default on every Solaris system. And even the concept of task is in use right now. Whenever a user log into a Solaris system, a new task is opened. Furthermore you will see, that all your services started by the Service management facility have their own task id. The SMF starts every service as a new task.

# ps -ef -o pid,user,zone,project,taskid,args | grep " 74 "
  653     root   global user.root    74 bash
  656     root   global user.root    74 ps -ef -o pid,user,zone,project,taskid,args
  657     root   global user.root    74 bash
  651     root   global user.root    74 sh

The projects are stored in a file per default, but you can use LDAP or NIS for a common project database on all your systems:

# cat /etc/project 
system:0::::
user.root:1::::
noproject:2::::
default:3::::
group.staff:10::::

A freshly installed system has already this pre-defined projects:

::: center
::: {#default}
[Project]{.smallcaps} [Description]{.smallcaps}
———————– ———————————————————————————————————————————-
system The system project is used for all system processes and daemons.
user.root All root processes run in the user.root project.
no.project The noproject project is a special project for IP Quality of Service. You can savely ignore it for this tutorial
default When there isn’t a matching group, this is the catch-all. A user without an explicitly defined project is member of this project
group.staff The group.staff project is used for all users in the group staff

Factory-configured project in Solaris ::: :::

[]{#default label=”default”}

Okay, but how do we create our own projects? It’s really easy:

[root@theoden:~]$ projadd -p 1000 testproject
[root@theoden:~]$ projmod -c "Testserver project" testproject
[root@theoden:~]$ projdel testproject

We created the project testproject with the project id 1000. Then we modified it by adding informations to the comment field. After this, we’ve deleted the project.

A practical example

Okay, I will use a practical example, now. We working as an administrator at the Unseen University. We’ve got a new system and want to create the users.

# useradd alice
# useradd bob
# useradd mike
# useradd laura

Looks familiar? I’ve omitted to set the password here. But of course you have to set one. Now we create some projects for two classes:

# projadd class2005
# projadd class2006

Okay. This projects have no users. We assign the project to our users.

# usermod -K project=class2005 alice
# usermod -K project=class2005 bob  
# usermod -K project=class2006 mike
# usermod -K project=class2006 laura

Like roles this assignments are stored in the file /etc/user_attr:

alice::::type=normal;project=class2005
bob::::type=normal;project=class2005
mike::::type=normal;project=class2006
laura::::type=normal;project=class2006

Okay, let’s su to the user alice and check for the project assignment:

bash-3.2$ su alice
Password: 
$ id -p
uid=2005(alice) gid=1(other) projid=100(class2005)

As configured the user alice is assigned to the project class2005. When we look into the process table, we can check the forth columns. All processes owned by alice are assigned to the correct project.

# ps -ef -o pid,user,zone,project,taskid,args | grep "class2005"
  752    alice   global class2005    76 sh
  758    alice   global class2005    76 sleep 10

Okay, obviously our teachers want their own projects: You can configure this on two ways. You can configure it by hand, or create a project beginning with user. and ending with the username. We use the second method in this example.

# useradd einstein
# projadd user.einstein
# passwd einstein
New Password: 
Re-enter new Password: 
passwd: password successfully changed for einstein

Now we check for the project:

$ su einstein
Password: 
$ id -p
uid=2009(einstein) gid=1(other) projid=102(user.einstein)
$ sleep 100 &
$ ps -ef -o pid,user,zone,project,taskid,args | grep "user.einstein"
  777 einstein   global user.einstein    78 sh
  782 einstein   global user.einstein    78 sleep 100
  788 einstein   global user.einstein    78 grep user.einstein
  789 einstein   global user.einstein    78 ps -ef -o pid,user,zone,project,taskid,args

Et voila! We don’t have to assign the project explicitly. It’s done automagically by the system.

The logic behind the automatic assigning of the project to a user is simple:

  • If the name of the project is defined by adding the project user attribute, use the assigned project as the default for the user.

  • If it’s not defined with the user, look for a project beginning with user. and ending with the name of the user and use it as default project. For example: user.root or user.jmoekamp

  • If there no such project, search for a project beginning with group. and ending with the name of the group of a user and use it as default project. For example: group.staff

  • If there«s no group with this name, use the project "default" as the default project.

But how do you create a task? You don’t have to configure tasks! A task is created automatically by the system in certain events. Those events are:

  • login

  • cron

  • newtask

  • setproject

  • su

Okay, let’s start a sleep in a new task:

$ newtask sleep 10 &
761

Okay, when you look at the process table now, you will see the different taskid in the fifth column:

# ps -ef -o pid,user,zone,project,taskid,args | grep "class2005"
  752    alice   global class2005    76 sh
  761    alice   global class2005    77 sleep 10

But you can use the newtask command to assign a different project, too. At first we create another project. We work at the Large Hadron Collider project, thus we call it lhcproject

$ newtask -p lhcproject sleep 100 &
802
$ newtask: user "einstein" is not a member of project "lhcproject"

Hey, not this fast! You have to be a member of the project to add a task to a project. Without this hurdle it would be too easy to use the resources of different project ;) Okay, let’s add the user einstein to the group lhcproject again.

# projmod -U einstein lhcproject

Now we can try it again:

$ newtask -p lhcproject sleep 1000&
817
$ ps -ef -o pid,user,zone,project,taskid,args | grep "einstein"
  777 einstein   global user.einstein    78 sh
  817 einstein   global lhcproject    80 sleep 1000
  819 einstein   global user.einstein    78 ps -ef -o pid,user,zone,project,taskid,args
  818 einstein   global user.einstein    78 grep einstein
$ 

Voila, the sleep runs within a different project.

Why do I need all this stuff?

But why is all this stuff important for Resource Management? While it’s possible to put resource management onto a single process, this isn’t a sensible choice most of the time. Your workload consists out of multiple services out of multiple processes and it would be more complex to configure resource management to each of this processes. With the concepts of projects and tasks you can assign those limits to a group of processes.

Limiting operating environment resources

The kernel of an operating system provides a huge amount of resources to the processes running on it. Such resources are file descriptors, shared memory segments or the process tables. Albeit hard to fill up this resources with modern operating systems it’s not impossible. When a resource is consumed by a single malicious or erroneous application, all other can’t run as well when they need more resources from the operating system.

Let’s assume this scenario: There is an course "Perl Scripting for beginners" at the Unseen University and in the last year the lesson "About fork" ended in chaos as some of your students coded forkbombs as they though this would be funny (as the class before, and the one before ...)

#!/usr/bin/perl
fork while 1

I’ve stored this little script at /opt/bombs/forkbomb.pl. A few seconds after starting such a script, the system is toast because of the hundreds of forked processes. Don’t try this without resource management. Okay, but this year, you’ve migrated to Solaris. You can impose resource management.

Okay, we have to modify our project configuration:

# projmod -K "task.max-lwps=(privileged,10,deny)" class2005

Now we have configured a resource limit. A single task in the class2005 cant have more than 9 processes. The tenth attempt to fork will be denied. Okay, do you remember the reasons, why the system starts a new task? One of it is "login". Thus every login of a user gives him 10 threads to work with. And this is exactly the behavior we want.

Let’s assume Alice starts her forkbomb:

# ps -ef | grep "alice"
   alice   685   682   0 14:58:12 ?           0:00 /usr/lib/ssh/sshd
   alice   693   686  14 14:58:42 pts/1       0:38 /usr/bin/perl /opt/bombs/forkbomb.pl
   alice   686   685   0 14:58:12 pts/1       0:00 -sh
   alice   694   693  15 14:58:42 pts/1       0:38 /usr/bin/perl /opt/bombs/forkbomb.pl
   alice   695   694  14 14:58:42 pts/1       0:37 /usr/bin/perl /opt/bombs/forkbomb.pl
   alice   696   695  14 14:58:42 pts/1       0:37 /usr/bin/perl /opt/bombs/forkbomb.pl
   alice   697   696  14 14:58:42 pts/1       0:37 /usr/bin/perl /opt/bombs/forkbomb.pl
   alice   698   697  14 14:58:42 pts/1       0:39 /usr/bin/perl /opt/bombs/forkbomb.pl
   alice   699   698  14 14:58:42 pts/1       0:38 /usr/bin/perl /opt/bombs/forkbomb.pl
# ps -ef | grep "alice" | wc -l
       9

After forking away 7 forkbomb.pl processes, any further fork is denied by the system. The load of the system goes up (as there are hundreds of denied forks) but the system stays usable.

Alice sends her script to Bob. He tries it, too:

# ps -ef | grep "alice"   
   alice   685   682   0 14:58:12 ?           0:00 /usr/lib/ssh/sshd
   alice 28520 28519   6 15:15:08 pts/1       0:03 /usr/bin/perl /opt/bombs/forkbomb.pl
   alice   686   685   0 14:58:12 pts/1       0:00 -sh
   alice 28521 28520   6 15:15:08 pts/1       0:03 /usr/bin/perl /opt/bombs/forkbomb.pl
   alice 28519   686   6 15:15:08 pts/1       0:02 /usr/bin/perl /opt/bombs/forkbomb.pl
   alice 28522 28521   6 15:15:08 pts/1       0:03 /usr/bin/perl /opt/bombs/forkbomb.pl
   alice 28524 28523   6 15:15:08 pts/1       0:03 /usr/bin/perl /opt/bombs/forkbomb.pl
   alice 28523 28522   6 15:15:08 pts/1       0:03 /usr/bin/perl /opt/bombs/forkbomb.pl
   alice 28525 28524   6 15:15:08 pts/1       0:02 /usr/bin/perl /opt/bombs/forkbomb.pl
# ps -ef | grep "bob"
     bob 28514 28511   0 15:14:47 ?           0:00 /usr/lib/ssh/sshd
     bob 28515 28514   0 15:14:47 pts/3       0:00 -sh
     bob  2789  2502   6 15:15:10 pts/3       0:03 /usr/bin/perl /opt/bombs/forkbomb.pl
     bob  2791  2790   6 15:15:10 pts/3       0:03 /usr/bin/perl /opt/bombs/forkbomb.pl
     bob  2502 28515   6 15:15:10 pts/3       0:03 /usr/bin/perl /opt/bombs/forkbomb.pl
     bob  2790  2789   6 15:15:10 pts/3       0:03 /usr/bin/perl /opt/bombs/forkbomb.pl
     bob  2792  2791   6 15:15:10 pts/3       0:03 /usr/bin/perl /opt/bombs/forkbomb.pl
     bob  2793  2792   6 15:15:10 pts/3       0:02 /usr/bin/perl /opt/bombs/forkbomb.pl
     bob  2794  2793   6 15:15:10 pts/3       0:03 /usr/bin/perl /opt/bombs/forkbomb.pl

This is still no problem for the system. After a few forks of the forkbomb, the system denies further forks. And the system stays usable. The limitation of the number of processes is only one example. You can limit other resources. You can find a list of all controls at the man page of resource_controls

Limiting CPU resources

Okay, but your system wasn’t purchased for students at night. You’ve bought it for computational science at night. The Large Hadron Collider project spend 75% of the costs, and the Small Hadron Collider project spend 25%. Thus the compute power should be distributed in a similar manner.

Without Resource Management

But when you start two compute intensive processes, both get roundabout 50 percent of processor. Okay, we have an super-duper simulation script called /opt/bombs/cpuhog.pl:

#! /usr/bin/perl
while (1) { my $res = ( 3.3333 / 3.14 ) }

Let’s login as user einstein:

# su einstein
Password:
$ /opt/bombs/cpuhog.pl &
$ /opt/bombs/cpuhog.pl &

After a few moments the system will stabilize at aprox. 50% CPU resources for both processes. Just look at the first column:

bash-3.2$ ps -o pcpu,project,args 
%CPU  PROJECT COMMAND
 0.0 user.einstein -sh
 0.3 user.einstein bash
47.3 user.einstein /usr/bin/perl /opt/bombs/cpuhog.pl
48.0 user.einstein /usr/bin/perl /opt/bombs/cpuhog.pl
 0.2 user.einstein ps -o pcpu,project,args

This isn’t the intended behavior.

Using the Fair Share Scheduler

Solaris can solve this problem. There is something called Fair Share Scheduler in Solaris. This scheduler is capable to distribute the compute power of the system based on a configuration. The FFS isn’t activated by default. You have to login as root to activate it:

# dispadmin -d FSS

There are ways to enable this scheduler with a running system, but it’s easier to reboot the system now.

When the system has started, we get root privileges by using su. At first we create an additional project for the SHC project. We created the other project (lhcproject) before:

# projadd shcproject
#projmod -U einstein shcproject

Now we configure an resource limit on the projects.

# projmod -K "project.cpu-shares=(privileged,150,none)" lhcproject
# projmod -K "project.cpu-shares=(privileged,50,none)" shcproject

We’ve used the resource control project.cpu-shares. With this control we can assign an amount of CPU power to an project. We’ve defined an privileged limit, thus only root can change this limit later on.

Shares

Okay, what is the meaning of these numbers 150 and 50 in the last commands ? Where are the 25% and the 75%? Well, the resource management isn’t configured with percentages, it’s configured in a unit called shares.

It’s like with stocks. The person with the most stocks owns most of the company. The project with the most shares owns most of the CPU. In our example we divided the CPU in 200 shares. Every share represents 1/200 of the CPU. Project shcproject owns 50 shares. Project lhcproject owns 150. I think, you already saw it: 150 is 75% of 200 and 50 is 25% of 200. Here we find our planed partitioning of the CPU we’ve planed before. By the way: I deliberately choose 150/50 instead of 75/25 to show you that these share definitions are not scaled in percent.

Okay, but what happens when you add a third project and you give this project 200 shares (For example because a new project gave money for buying another processor board). Then the percentages are different. In total you have 400 shares on the system. The 200 shares of the new project are 50%, thus the project gets 50% of the compute power. The 150 shares of the lhcproject are 37.5 percent. This project gets 37.5 of the computing power. And the 50 shares of the shcproject are now 12.5 percent and thus the project get this part of the CPU power.

Behavior of processes with Resource Management

Okay, now let’s start a process under the control of the new resource limitation. Login as user einstein and type the following command:

$ newtask -p shcproject /opt/bombs/cpuhog.pl &

We start at first only one of the cpuhog.pl processes .

bash-3.2$ ps -o pcpu,project,args
%CPU  PROJECT COMMAND^
 0.0 user.einstein -sh
 0.3 user.einstein bash
 0.2 user.einstein ps -o pcpu,project,args
95.9 shcproject /usr/bin/perl /opt/bombs/cpuhog.pl

Wait ... the process gets 95.9 percent? An error ? No. It makes no sense to slow down the process, when there is no other process needing the compute power.

Now we start the second process, this time as a task in the lhcproject:

bash-3.2$ newtask -p lhcproject /opt/bombs/cpuhog.pl &
[2] 784

We look in the process table again.

bash-3.2$ ps -o pcpu,project,args
%CPU  PROJECT COMMAND
 0.0 user.einstein -sh
 0.1 user.einstein bash
72.5 lhcproject /usr/bin/perl /opt/bombs/cpuhog.pl
25.6 shcproject /usr/bin/perl /opt/bombs/cpuhog.pl
 0.2 user.einstein ps -o pcpu,project,args

Voila, each of our compute processes get their configured part of the compute power. It isn’t exactly 75%/25% all the time but in average the distribution will be this way.

A few days later, the Dean of the department comes into the office and tells you that we need the results of the SHC project earlier, as important persons want to see them soon to spend more money. So you have to change the ratio of the shares. We can do this without restarting the processes at runtime. But as we’ve defined the limits as privileged before, we have to login as root:

# prctl -n project.cpu-shares -r -v 150 -i project shcproject
# prctl -n project.cpu-shares -r -v 50 -i project lhcproject

Let’s look after the processes again after a few moments:

bash-3.2$ ps -o pcpu,project,args
%CPU  PROJECT COMMAND
 0.0 user.einstein -sh
 0.1 user.einstein bash
25.7 lhcproject /usr/bin/perl /opt/bombs/cpuhog.pl
72.9 shcproject /usr/bin/perl /opt/bombs/cpuhog.pl
 0.2 user.einstein ps -o pcpu,project,args

The ratio has changed to new settings. It’s important to know that only the settings in /etc/projects is boot-persistent. Everything you set via prctl is lost at the boot.

Limiting memory resources

So far we configured limits on the usage of operating system resources and the CPU. Let’s get back to the class room example used before. A different course at the unseen university is "Memory Management for beginners". And at start our students have problem with severe memory leaks. It would be useful to impose resource management to the memory management.

Without memory resource management

Bob wrote a little script within Perl that eats a large amount of the available memory.

#!/usr/bin/perl
for ($i=0;$i<10;$i++) { 
 push @_,"x"x(1*1024*1024);
 sleep(5);
}
sleep(30);
for ($i=0;$i<10;$i++) { 
 push @_,"x"x(1*1024*1024);
 sleep(5);
}

When we start this script, it will allocate memory by pushing blocks of 1 Megabyte of x chars onto a stack.

# ps -ef -o pid,user,vsz,rss,project,args | grep "bob" | grep -v "grep"
 1015      bob 8728  892 class2005 /usr/lib/ssh/sshd
 1362      bob 26148 24256 class2005 /usr/bin/perl ./memoryhog.pl
 1016      bob 1624  184 class2005 -sh
 1031      bob 3260 1336 class2005 bash

When you look in the forth column you see the resident set size. The resident set is the amount of data of a process in the real memory. After a short moment the process ./memoryhog.pl uses 24 MB of our precious memory (20 times 1 MB plus the perl interpreter minus some shared stuff).

With memory resource management

It would be nice to control the amount of data, that resides in the real memory. Solaris has such a capability. At first we have to activate the resource cap enforcement daemon. You have to login as root to do so:

# rcapadm -E

The rcapd daemon enforces resource caps on a group of processes. The rcapd supports caps on projects and zones at the moment. When the resident set size of a group of processes exceeds the defined cap. To reduce the resource consumption of a process group, the daemon can page out infrequently uses pages of memory to swap.

For testing purposes we configure the daemon in such a way, that it scans every second for new processes in projects with a resource cap. Furthermore we configure it to sample the resident set size every 1 second, too. Additionally the pageout statistics of the rcapd will be updated every second, too.

# rcapadm -i scan=1,sample=1,report=1

For testing purposes we define a new project called mmgntcourse and add the user bob to this project:

# projadd mmgntcourse
# projmod -U bob mmgntcourse

Now we set an resource cap for the resident set size of 5 Megabytes for this project:

# projmod -K rcap.max-rss=5242880 mmgntcourse

Okay, now get back to the window with the login of user <code>bob</code>. Let’s start the memoryhog.pl in the mmgntcourse:

$ newtask -p mmgntcourse ./memoryhog.pl

Okay, get back to a different window and login as root. With the rcapstat you can observe the activities of the rcapd. In our example we tell rcapstat to print the statistics every 5 seconds:

 # rcapstat 5
    id project         nproc    vm   rss   cap    at avgat    pg avgpg
   105 mmgntcourse         - 2352K 3876K 5120K    0K    0K    0K    0K
   105 mmgntcourse         - 3376K 4900K 5120K    0K    0K    0K    0K
   105 mmgntcourse         1 4400K 5924K 5120K  812K  812K  804K  804K
   105 mmgntcourse         1 5424K 6408K 5120K 3380K 1126K 3380K 1126K
   105 mmgntcourse         - 6448K 4856K 5120K    0K    0K    0K    0K
   105 mmgntcourse         1 7472K 5880K 5120K  760K  760K  760K  760K
   105 mmgntcourse         1 8496K 5384K 5120K 1024K  512K 1024K  512K
   105 mmgntcourse         1 9520K 6144K 5120K 1024K 1024K 1024K 1024K
   105 mmgntcourse         1   10M 5120K 5120K 1024K 1024K 1024K 1024K
   105 mmgntcourse         1   11M 6144K 5120K 1024K 1024K 1024K 1024K
   105 mmgntcourse         1   11M 4096K 5120K 1024K 1024K 1024K 1024K
   105 mmgntcourse         -   11M 4096K 5120K    0K    0K    0K    0K
[...]
   105 mmgntcourse         -   11M 4096K 5120K    0K    0K    0K    0K
   105 mmgntcourse         1   14M 5892K 5120K 2820K  940K 2820K  940K
   105 mmgntcourse         1   15M 5628K 5120K 1280K  640K 1280K  640K
   105 mmgntcourse         1   16M 6144K 5120K 1024K 1024K 1024K 1024K
   105 mmgntcourse         1   17M 6144K 5120K 1024K 1024K 1024K 1024K
   105 mmgntcourse         1   18M 5120K 5120K 1024K 1024K 1024K 1024K
   105 mmgntcourse         -   18M 5120K 5120K    0K    0K    0K    0K
   105 mmgntcourse         1   20M 5120K 5120K 2048K 1024K 2048K 1024K
   105 mmgntcourse         -   20M 5120K 5120K    0K    0K    0K    0K
   105 mmgntcourse         1   22M 5120K 5120K 2048K 1024K 2048K 1024K

As you see, the resident set size stays at approx. 5 Megabyte. The RSS may increase above the configured size, as the applications may allocate memory between the RSS sampling intervals. But at the next sampling size the rcap starts to force the page out of this exceeding pages. After a few seconds the resident set size is enforced, again. You can observe this behaviour in column 5 of the rcapstat printout.

Resource Management and SMF

A few days ago, I wrote about the Service Management Facility, a framework to manage services in Solaris. This framework enables Solaris to start services in a more intelligent manner. Albeit almost all services started by SMF are member of the project <code>system</code> it doesn’t have to be this way. You can specify the project used for a service.

Assigning a project to an already running service

This method is described in the SMF FAQ[^2]. I will use an practical example. You run a server in the internet, but it’s under high load from spam bot. You’ve already created a project sendmail and configured the resource management.

At the moment, the sendmail runs in the system project:

# ps -o pid,project,args  -ef | grep "sendmail" | grep -v "grep" 
  648   system /usr/lib/sendmail -Ac -q15m
  647   system /usr/lib/sendmail -bd -q15m -C /etc/mail/local.cf

How do you start it as a part of a different project? Okay, check for an already configured project.

#  svcprop -p start/project smtp:sendmail
svcprop: Couldn't find property `start/project' for instance `svc:/network/smtp:sendmail'.

Okay, nothing defined ... this makes it a little bit harder, because we can’t set the project only at the moment, as there is a bug in the restarter daemon. You need a fully populated start method. If the svcprop run delivers you the name of a project, you can ignore the next block of commands:

svccfg -s sendmail setprop start/user = astring: root
svccfg -s sendmail setprop start/group = astring: :default
svccfg -s sendmail setprop start/working_directory = astring: :default
svccfg -s sendmail setprop start/resource_pool = astring: :default
svccfg -s sendmail setprop start/supp_groups = astring: :default
svccfg -s sendmail setprop start/privileges = astring: :default
svccfg -s sendmail setprop start/limit_privileges = astring: :default
svccfg -s sendmail setprop start/use_profile = boolean: false

Okay, now we can set the project property of the start method:

svccfg -s smtp/sendmail setprop start/project = astring: sendmail
\end{lstlsting}
Now we have to refresh the configuration of the service. After refreshing the service we can check the property:
\begin{lstlisting}
# svcadm refresh sendmail
#  svcprop -p start/project sendmail
sendmail

Okay, the new properties are active. Now restart the service:

# svcadm restart sendmail

Let’s check for the result:

# ps -o pid,project,args  -ef | grep "sendmail" | grep -v "grep" 
 1539 sendmail /usr/lib/sendmail -bd -q15m -C /etc/mail/local.cf
 1540 sendmail /usr/lib/sendmail -Ac -q15m

Configuring the project in a SMF manifest

Okay, you have written your own application and want to run it under the control of the SMF. You can define the project for the service in the manifest. You have to define the project in the start method of the manifest:

<exec_method type='method' name='start' exec='/path/to/method start' timeout_seconds='0' >
        <method_context project=projectname'>
        <method_credential user='someuser'>
        </method_context>
	   </exec_method>

That’s all. The important part is the second row of the fragment. We define the project as a part of the startup method context. The rest is done as described in the SMF tutorial[^3]

Conclusion

The Solaris Resource Management is an powerful tool to partition the resources of a single instance of an operating system. By using Solaris Resource Management you can use a single operating system for a multitude of services but still ensuring the availability of resources to them. I hope, this tutorial gave you an good insights into the basics of resource management.

Do you want to learn more?

Documentation

System Administration Guide: Solaris Containers-Resource Management and Solaris Zones

man page for resource_controls(5)

man page for the Fair Share Scheduler

Misc. links

Zones and Containers FAQ - Section 3: Resource Management, Performance

Solaris 10+ Resource Management