Saturday, November 24, 2007

Using Solaris 10 Projects Absolutely or Per Process!

Most Solaris 10 users and admins already know that a whole lot about the Solaris OS changed when they switched from version 9 to 10. One of the most significant things that changed is the way Solaris deals with internal IPC settings, semaphores, shared memory and other kernel tunables.

In all previous versions, you needed to include those sorts of settings in /etc/system. The upside to this was that you could include all of your information in one file and easily report on all of your information by calling a common system command like "sysdef." Of course, one of the big disadvantages of having to set all of that stuff up in /etc/system was that you had to reboot your machine, every time you made a change, in order for the settings to take effect (/etc/system is read during the boot process at a level which can't be simulated at any user-operable run level)

In Solaris 10, a lot of the old setting in /etc/system have been deprecated. You can still include them without causing a problem with your boot process, but Solaris 10 will ignore most of the options you put in there with regards to the old system settings. The new preferred way of setting these variables in Solaris 10 is the "project." Among its many advantages, you can now modify a lot of settings, that used to require a reboot, on-the-fly!

This post isn't going to go into the entire "project" concept, but, instead, focus on two different ways of using it. That is, we'll be looking at using "project" settings on a "per user" basis and a "per action" basis.

Enabling project settings on a "per user" basis is generally preferred by most users. For instance, the oracle user account will want to have the maximum amount of shared memory set to an exact value in the kernel whenever it is invoked. The settings need to be the same all the time, and enabling project settings on "per user" basis is the easiest way to accomplish that.

For a small example; here is how we would set the oracle user up to always have its shared memory maximum set to 17GB (now matter how the account is called or used):

projadd -p 101 -c "Oracle User Account" -K "project.max-shm-memory=(privileged,17GB,deny)" -U oracle -G dba

This will create an entry in /etc/project like: User Account:oracle:dba:project.max-shm-memory=(privileged,17179869184,deny)

and you can check it out by running:

prctl $$

after logging in, to verify that things are as you like.

Now, you may want to make it so these values can be used on a "per action" basis. This way the user can log in and not necessarily have to use the project values assigned. This is preferrable if you only need to run certain processes with the project settings, but don't want them set while you do other things. The process is pretty much the same:

projadd -p 101 -c "Oracle User Account" -K "project.max-shm-memory=(privileged,17GB,deny)" -G dba

This will create an entry in /etc/project like: User Account::dba:project.max-shm-memory=(privileged,17179869184,deny)

Now when the user logs in, he or she can verify that the "project" settings aren't in effect by running "prctl $$" as above. Output should show that user is in the default project for the OS. He or she can now also take advantage of the project settings by using a command called "newtask," like so:

newtask -p COMMAND

or attach to an existing process with:

newtask -v -p -c PROCESS_ID

For the "per task" processes, you can verify that they're in effect for the process you started (or attached to) them with by doing:

prctl -i PROCESS_ID


prctl -n (with, optionally, "-i PROCESS_ID" -- Running this without specifying the PROCESS_ID will show all processes running under the project resource.

And that's it. Play around with it and have fun. Like we mentioned before, you can try this out a couple different ways until you get it just the way you like. With the new "project" method of setting kernel tunables, you'll not have to reboot any more between your iterations :)

, Mike