Implementing shared memory resource controls on Solaris hosts

With the availability of the Solaris 10 operating system, the way IPC facilities (e.g., shared memory, message queues, etc.) are managed changed. In previous releases of the Solaris operating system, editing /etc/system was the recommended way to increase the values of a given IPC tunable. With the release of Solaris 10, IPC tunables are now managed through the Solaris resource manager. The resource manager makes each tunable available through one or more resource controls, which provide an upper bound on the size of a given resource.

Merging the management of the IPC facilities into the resource manager has numerous benefits. The biggest benefit is the ability to increase and decrease the size of a resource control on the fly (prior to Solaris 10, you had to reboot the system if you made changes to the IPC tunables in /etc/system). The second major benefit is that the default values were increased to sane defaults, so you no longer need to fiddle with adjusting the number of message queues and semaphores when you configure a new Oracle database. That said, there are times when the defaults need to be increased. If your running Oracle, this is especially true, since the default size of the shared memory resource control (project.max-shm-memory) is sized a bit low (the default value is 254M).

There are two ways to increase the default value of a resource control. If you want to increase the default for the entire system, you can add a resource control with the desired value to the system project (projects are used to group resource controls). If you want to increase the value of a resource control for a specific user or group, you can create a new project and then assign one or more resource controls to that project.

So lets say that you just installed Oracle, and got the lovely “out of memory” error when attempting to create a new database instance. To fix this issue, you need to increase the amount of shared memory that is available to the oracle user. Since you don’t necessarily want all users to be able to allocate gobs of shared memory, you can create a new project, assign the oracle user to that project and then add the desired amount of shared memory to the shared memory resource control in that project

To create a new project, the projadd utility can be executed with the name of the project to create:

$ projadd user.oracle

Once a project is created, the projmod utility can be used to add a resource control to the project (you can also edit the projects file directly if you want). The following example shows how to add a shared memory resource control with an upper bounds of 1GB to the user.oracle project we created above:

$ projmod -sK “project.max-shm-memory=(privileged,1073741824,deny)” user.oracle

To verify that a resource control was added to the system, the grep utility can be run with the project name and the name of the system project file (project information is stored in /etc/project):

$ grep user.oracle /etc/project
user.oracle:100::::project.max-shm-memory=(privileged,1073741824,deny)

You can also check the value of a resource control with the prctl utility. Prctl takes a pid as an argument and optionally the name of the resource control to print (prctl will print the value of all resource controls by default):

$ prctl -n project.max-shm-memory $$

process: 585: -sh
NAME    PRIVILEGE       VALUE    FLAG   ACTION                       RECIPIENT
project.max-shm-memory
        privileged      1.00GB      -   deny                                 -
        system          16.0EB    max   deny                                 -

The resource control facility is amazingly cool, and the folks who manage the Princeton Solaris support repository did a great job documenting it.

One Comment

brett  on May 23rd, 2007

Worth mentioning that in OpenSolaris b59+ or Solaris 7/07, resource controls for non-global zones are handled in the zone configuration, eg:

rctl:
name: zone.max-sem-ids
value: (priv=privileged,limit=256,action=deny)
rctl:
name: zone.max-shm-memory
value: (priv=privileged,limit=4294967296,action=deny)

Leave a Comment