[net.unix] answer to my accounting question

HEDRICK@RUTGERS.ARPA (07/09/84)

From:  Charles Hedrick <HEDRICK@RUTGERS.ARPA>

(In interpreting the following message, you may find it useful to know
that we are using a Pyramid, primarily on the 4.2bsd side.)

As you may recall, I asked some time ago for suggestions about how to
do accounting.  I had the following problems with the normal Unix
software:
  - it has no idea about accounts.  Reports just show lists of users.
	For a student system, we are interested in knowing how much
	each class is using.  We also want to be able to mail
	reports to each instructor every 2 weeks showing what his
	class is doing.  Note that some students will be in more
	than one class.  We don't want separate user names for them
	in this case.
  - the process accounting file grows very quickly.  It seems 
	unnecessary to make an entry for each individual process.

Here is the design I have adopted.  I believe it is very similar
in concept (although not implementation) to something the folks at
Utah are using:

  - we use the group number as an "account".  Following a suggestion
	from the folks at Utah, we will probably use the password
	field in /etc/groups (which they assure me no one actually
	uses for anything) to contain the account name associated
	with the group.  We don't want to use the group name, because
	often several groups are associated with one account (since
	we may establish groups for file sharing purposes).  Note that
	this is only an approproximation.  It would be much nicer to
	have an actual account attribute, but it would require more
	kernel changes than I want to make, since every process and
	file would have to have an associated account.
  - login is modified to ask you for your account after it has taken
	your password.  At the moment what it is looking for is a group
	name.  If this group name is not valid for you, it prints a list
	of all the valid ones and asks you again.
  - login maintains a file /usr/adm/checkpoint.bin.  This is similar
	to utmp in its structure, except that it also has the gid
	that you supplied to login.  The main purpose of this file
	is so that init can figure out what account (gid) you are
	using when you log out.  This could also be done by adding
	a gid field to utmp.  (Indeed that's what Utah does.)
	Since the whole world knows about utmp, we didn't want to
	recompile the necessary utilities.  This is more important
	for us than for people on a VAX, since Pyramid is currently
	giving us new releases of the system about every 6 weeks.
  - date is modified to adjust all the login times if you change the
	time.  (I did this before I found out that it is a bad
	idea to change the date/time while timesharing is going on.
	Apparently it causes cron to spawn very large numbers of jobs,
	unless the time change is very small.)
  - init is modified in two ways:
 	when you log out, if it recognizes the process (i.e. it is
		a child of init), it uses the record in checkpoint.bin
		to compute connect time.  The logic is parallel to
		the way to handles utmp and wtmp.  It writes a
		connect time record into /usr/adm/system-data.bin
	most of the wait's are now wait3's.  When a wait3 is satisfied,
		init writes a CPU time entry into
		/usr/adm/system-data.bin.  This code is not within the
		test for child of init, so it should work for any
		process.  To avoid having the file grow very quickly due
		to all those open lines and their spurious logins, init
		does not write entries when the CPU time is less than 1
		sec.  (The CPU time entries are in seconds.  Since I am
		handling a whole job at once in most cases, this should
		be safe.)
  - I will port my Tops-20 accounting software.  This is a set
	of Pascal programs that produce reports that are concise, but
	reflect project and departmental structures.  (That is, you
	can specify groupings of accounts that get a subtotal.  In
	fact, the programs read a file that specifies a general 
	tree structure of totals and subtotals.)

A kernel change is required in order to give WAIT3 enough information
to do this.  WAIT3 will return as much as you could ever want to
know about the resources used by the process.  Unfortunately, there is
no way to know who to charge.  If you are dealing with a child of 
init, of course that's easy.  You have the uid and gid in 
/usr/adm/checkpoint.bin (the file that is parallel to utmp).  However
if somebody left a process around in the background before logging off,
when that process terminates init has no idea who it is.  The obvious
solution is to add fields to rusage that give the uid and gid of the
process.  Conceptually, that is what I have done.  (In fact, I have
picked what I think is the least useful of the statistics in the
rusage record and recycled it.  Again, if I add a field to this
record, I have to recompile the whole world.)  A warning to anyone
else trying to implement this:  I also had to recycle a field in the
process record.  I need a field so that EXIT can pass the gid to WAIT.
There is already a p_ruid field which has the uid, but there is no
p_rgid field. The gid is kept in the user record.  Unfortunately, by the
time we get to wait, the pages containing this record have been
deallocated, so I have to save away this value.  (The particular
field that I used would not be of interest to most of you, as it
is specific to the Pyramid implementation.)

This experience points up dramatically the difference between Tops-20
and Unix.  In Tops-20, it would have been very easy to add a new field
to the rusage record.  In Tops-20, anyone who wanted this record would
pass the monitor two arguments: the address where he wanted it and the
number of words he wanted.  Thus we would add new fields at the end, and
old programs wouldn't be bothered.  Also, I would not have had to
create a separate data structure (checkpoint.bin) parallel to an
existing one (utmp) just to avoid recompiling all the utilities.  User
programs do not directly access system data structures.  Instead, they
ask the monitor for the information.  Often the monitor has better
ways of storing it that in the simple sequential files typically used
in Unix.  But at any rate, it would never be necessary to recompile
(or even relink) anything more than the monitor to change a system data
structure.
-------