Overview #
We did a Migrating From NIS To LDAP project for a client that was using a lot of Solaris with NIS.We came up with SolarisNISProjectSchema Schema Extensions to make things work in the late 1990s.
As near as we know, projects are a Solaris Specific NIS Map.
The key file to keep track of here is the project database, /etc/project.
The project file contains a series of one-line entries, one for each configured project. (If you don't want to edit the /etc/project file by hand, you can use the projadd, projdel, and projmod commands to add, remove, or modify projects, respectively.)
Each line takes the following form (LDAP Attribute Name):
project-name:project-id:comment:user-list:group-list:attributes
- The project-name field (SolarisProjectName) is the name of the project, and must be specified as an alphanumeric string--periods (.) and colons (:) are not allowed.
- The project-id field (SolarisProjectID) is a unique numerical identifier for the project. The maximum project ID is 2,147,483,647; project IDs between 0 and 99 are reserved for the system.
- The comment field (description) is a description of the project.
- The user-list (memberUid) is a list of all the users who are allowed to associate with the project. Wildcards are allowed: an asterisk (*) permits all users to join the project, and an exclamation point (!) followed by a username excludes that user. An exclamation point followed by an asterisk (!*) excludes all users.
- The group-list field (memberGid) is analogous to the user-list field. Wildcard constructs are valid here, just as they are in the user-list field.
- The attributes field (SolarisProjectAttr) defines the resource-control attributes associated with the project.
Here are a few of the most "attributes" interesting options:#
task.max-cpu-time | The maximum amount of CPU time available to all the processes in this project (in milliseconds). |
task.max-lwps | The maximum number of lightweight processes available to all the processes in this project. |
process.max-cpu-time | The maximum amount of CPU time available per process for each process in this project (in milliseconds). |
process.max-file-descriptor | The maximum number of file descriptors permitted to each process in this project. |
process.max-file-size | The maximum file size available to processes in this project (in bytes). |
process.max-core-size | The maximum size for a core file created by a process in this project (in bytes). |
process.max-data-size | The maximum heap size for a process in this project (in bytes). |
process.max-stack-size | The maximum stack size for a process in this project (in bytes). |
process.max-address-space | The maximum amount of address space (over all segments) available for a process in this project (in bytes). |
Each attribute is specified by setting it equal to a triplet, like this:
attribute=(privlevel,value,action)
There are three available values for privlevel. The first, "basic", means that the threshold can be modified by the process, without any special privileges; the second, "privileged", means that the threshold can be changed only by the superuser; the third, "system", means that the threshold is fixed for the duration of the operating system instance (for example, until a reboot).
Multiple attributes can be specified for a single project; separate them with semicolons.
Now that we've walked through the theory, let's create a project.
We can put the following line in /etc/project:
test:10000:test project:jqpublic::process.max-file-size=(privileged,16777216,deny)
Alternatively, we could run projadd to create this project:
# projadd -p 10000 -c 'test project' -U jqpublic test # grep ^test: /etc/project test:10000:test project:jqpublic::(Note that projadd and projmod won't let you change the resource-control field.)
This project is named "test" and has a project ID of "10000". Membership is restricted to the user "jqpublic," and any project running in the test project will not be allowed to create a file greater than 16MB (16MB = 16,777,216 bytes).
When jqpublic next logs in, they can run `projects` to get a list of all the projects they are allowed to participate in:
jqpublic@purgatorio% projects default group.staff testTo find out which project is associated with the currently running shell, try id -p:
jqpublic@purgatorio% id -p uid=127(jqpublic) gid=10(staff) projid=10(group.staff)(A user's default project can be changed by editing /etc/user_attr. The syntax to use for this is "username::::project=projectname". For example:
gdm::::project=testFor more information, consult the man page for user_attr(4).).
In this case, jqpublic's project is 'default.' This project has no resource constraints assigned to it. Let's confirm that the resource limitation works on the maximum file size we defined for the test project:
jqpublic@purgatorio% id -p uid=127(gdm) gid=10(staff) projid=10(group.staff) jqpublic@purgatorio% mkfile -v 32M testfile.project=default testfile.project=default 33554432 bytes jqpublic@purgatorio% newtask -p test csh jqpublic@purgatorio% id -p uid=127(gdm) gid=10(staff) projid=10000(test) jqpublic@purgatorio% mkfile -v 32M testfile.project=test testfile.project=test 33554432 bytes Could not set length of testfile.project=test: File too largeThe resource constraint worked!
You can also set up the resource-management framework so that it writes a notification to the syslog when a resource control is tripped. This can be done via rctladm:
# rctladm -e syslog process.max-file-descriptor # rctladm |grep process.max-file-size process.max-file-size syslog=notice [ lowerable deny file-size ]An attempt by a user in the 'test' project to generate a 32MB file generates the following warning in /var/adm/messages:
Jun 24 23:33:09 british-museum.internal genunix: [ID 883052 kern.notice] privileged rctl process.max-file-size (value 16777216) exceeded by process 2428
One other interesting feature about projects is that the prstat command can summarize running processes by project, if you give it the -J switch. This can be quite useful if, for example, you have a "Webserver" project to which all your Web server daemons belong. (If you aren't familiar with prstat, I encourage you to play around with it: it's a useful application. It gives output that is quite similar to that of top, but it is more lightweight. It became available in Solaris 8.)
jqpublic@purgatorio% prstat -cJ