[net.unix-wizards] maxusers in config file

coltoff@burdvax.UUCP (Joel Coltoff) (01/10/85)

< *********** >

A deparate cry for 4.2bsd help,

	We have maxusers set to 32 in our config file. Today we had
36 people logged in. I've done my best in tracking down what could
be going on but I am a hardware jock and can only do so much when
it comes to the kernel. Anyway the login program calls a function
quota() which is supposed to check to see if you've hit the login
limit. This I track down to the qquota() function in /sys/sys/quota_sys.c
To my surprise this code does nothing if QUOTA is not defined during
compilation. This we had done but login limits and quota limits
are two separate things and I expected to see some code after the
ifdef. Can somebody ( via mail ) give me an indication as to what
might be wrong. This situation can't be good for the machine. I imagine
that the maxusers number sets up tables somewhere that have overflowed
and steped on some important memory location. It's like trying to jam
12 bits into an 8 bit register.

Again please respond by mail. This isn't a group I normally read.

	Thanks in advance,
-- 

	Joel Coltoff	{sdcrdcf,bpa,psuvax1}!burdvax!coltoff
			(215)648-7258

chris@umcp-cs.UUCP (Chris Torek) (01/16/85)

Sigh.  ``maxusers'' doesn't limit the number of people who can log in;
it's supposed to be the largest number of people you expect to be bashing
away at any one time.  It controls the size of a lot of system tables.
If those tables overflow, you get lots of things printed on your console,
and programs won't run, but nothing drastic happens.

You can have maxusers set to 10 and have 10 thousand people logged in;
the system won't care, but only about 10 of them will have enough resources
available to get things done.

If you aren't getting ``file table full'' or ``inode table full'' or
shell gripes about ``no more processes'' when starting programs, then
your maxusers is probably not set too small.
-- 
(This line accidently left nonblank.)

In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
UUCP:	{seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland

ed@mtxinu.UUCP (Ed Gould) (01/19/85)

> Sigh.  ``maxusers'' doesn't limit the number of people who can log in;
> it's supposed to be the largest number of people you expect to be bashing
> away at any one time.  ...
> 
> You can have maxusers set to 10 and have 10 thousand people logged in;

In order to comply with AT&T's restrictions on binary licenses, we've
added a maxusers() system call that returns the value from the
config maxusers parameter.  The limit is enforced by login(1),
by counting the numbers of entries in /etc/utmp.

-- 
Ed Gould		    mt Xinu, 739 Allston Way, Berkeley, CA  94710  USA
{ucbvax,decvax}!mtxinu!ed   +1 415 644 0146

chris@umcp-cs.UUCP (Chris Torek) (01/21/85)

[Please excuse the ravings; this is one of my favorite subjects for
frothing at the mouth]

> In order to comply with AT&T's restrictions on binary licenses, we've
> added a maxusers() system call that returns the value from the
> config maxusers parameter.

ANOTHER SYSTEM CALL just for ONE STUPID INTEGER?!  What is this anyway?
How about having a single system call, ``getinterestingkernelnumber'',
which takes an argument describing which integer to return?

[There, I feel much better now...]
-- 
(This line accidently left nonblank.)

In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
UUCP:	{seismo,allegra,brl-bmd}!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland

James Matheson <jmrm@eng-dsl> (01/21/85)

Ed Gould writes
> In order to comply with AT&T's restrictions on binary licenses, we've
> added a maxusers() system call that returns the value from the
> config maxusers parameter.  The limit is enforced by login(1),
> by counting the numbers of entries in /etc/utmp.

This will only work if the login process used actually updates
utmp. People could get round this by writing their own /bin/login
without this feature and hey presto no limit!

dave@lsuc.UUCP (David Sherman) (01/25/85)

In article <7602@brl-tgr.ARPA> James Matheson <jmrm@eng-dsl> writes:
||Ed Gould writes
||> In order to comply with AT&T's restrictions on binary licenses, we've
||> added a maxusers() system call that returns the value from the
||> config maxusers parameter.  The limit is enforced by login(1),
||> by counting the numbers of entries in /etc/utmp.
||
||This will only work if the login process used actually updates
||utmp. People could get round this by writing their own /bin/login
||without this feature and hey presto no limit!

Or, even simpler, remove /etc/utmp! (So who needs who(1) anyway?)

Dave Sherman
-- 
{utzoo pesnta nrcaero utcs}!lsuc!dave
{allegra decvax ihnp4 linus}!utcsrgv!lsuc!dave

kre@munnari.OZ (Robert Elz) (01/27/85)

First, please excuse this flame in unix-wizards.  You may feel that
net.flame would be a better choice of group, but (un)fortunately
we don't get this in Australia.  I wouldn't have used it anyway,
as I really do feel that this flame contains at least a basis of
wizardly material.  Remember if you flame at me for flaming here,
you're just compounding my sin.  Also I have waited a couple of
days since this message appeared - supposedly to allow my temper
to cool, all that's its done though is fan the flames...

Now, gloves on, goggles down, away we go.

In article <2622@umcp-cs.UUCP> chris@umcp-cs.UUCP (Chris Torek) writes:
| > In order to comply with AT&T's restrictions on binary licenses, we've
| > added a maxusers() system call that returns the value from the
| > config maxusers parameter.
| 
| ANOTHER SYSTEM CALL just for ONE STUPID INTEGER?!  What is this anyway?
| How about having a single system call, ``getinterestingkernelnumber'',
| which takes an argument describing which integer to return?

I don't believe this crap!  I'm going to attack it from two angles.

First, there are two ways that you can define "system call" for this
purpose.  The one I feel sure Chris means, is "the number of entries
that aren't nullsys or nosys in the syscall array".  (If I'm wrong
never mind, I'll get to the other one).

On this assumption - WHO CARES???  What difference can it possibly make??
How the syscall array is used by some particular kernel implementation
is surely entirely a matter for that implementation.

The most obvious thing to say first, is that on one view, on a vax
(that's what Ed Gould was referring to in his original posting, I'm sure),
the number of system calls is 1.  It takes an argument telling which
particular function to perform.  Just like Chris wants.  Minimal even!

On a 68k (or a Perkin-Elmer) the number of sys calls is 16,
in most implementations just one of them is used.  Pdp-11's
are a vague area, you can consider there to be 1 or 64 sys calls.
(or 4 or 130 if you want to count the TRAP EMT BPT and IOT instrs
in various ways).

The method that the implementation uses to choose the particular
function to be performed given the particular hardware sys call
instructions available must be one of the most irrelevant matters
for argument of all time.  It used to be material when we all coded
in assembler - maybe Chris still does???

A couple of examples:  most 68k implementations that I've
seen use just one of the "trap" instructions for all kernel
entries.  A particular implementation might decide that as
"read" and "write" are executed orders of magnitude more
often than the other sys calls, they can gain some precious
cpu time by using two of the otherwise unused "trap" instrs
for those functions, give them idealized parameter passing
(eg: all params in registers, so no validation needs to
be done to get the args) and perhaps gain a 100 usecs or so
over the "standard way".  That just might be the edge they
need over the competition.

What would that do to your "sys call counting"?  Are they
two extra sys calls, or not?  They're certainly different
from the standard syscalls.

Another.  There's this processor I know 
	[which I won't name, as this just might be covered by
	non-disclosure - but if I don't tell you which I'm talking
	about, only those people who've already been disclosed to
	are going to recognise this, right?  Also, I'm going to
	change the facts (and introduce some errors that I know
	are here, so don't bother to read this as a precise spec)
	which will further hide things]
which has the clock register in user readable address space.
In the unix implementation for this processor, the "time" syscall
can be "eliminated", and replaced by a little bit of "as" code
that reads the clock register and does the little bit of arithmetic
needed to turn it into unix format.  Much cheaper than the overhead
of a switch to kernel mode.  There's also a register that gives
the cpu time used by the current process.  With that, and by having
all sys calls return the "sys" time used by the process (to the "as"
interface code, that then salts this away somewhere before returning
to the user code), and the "wait" sys call returning the child cpu/sys
times, the "times" sys call can also be done away with.

Do we applaud this implementation for saving two system calls ???

I don't - its probably an intelligent implementation decision,
but nothing more than that.

So, lets drop all this crud about system call counting, eh?
It's simply and totally irrelevant to everything.


Now for the 2nd possible interpretation of "system call".  What
it might be used to mean is a kernel service.  That is, something
provided by the OS implementation to users.

With this definition, "maxusers" is a new sys call, whether its
implemented as a function name in the syscall array in the kernel,
or whether its implemented in a case statement in the
"getinterestingkernelnumber" function in the kernel (which is
in the syscall array).  Its new functionality, and thus
a new system call.

My only remarks about this (I'm not about to get into whether
maxusers() is a useful addition or not) is that if its going
to be done, to the C (or whatever) programmer it MUST appear
as a new function, not as an appendage to some other unrelated
function.

Whether maxusers is implemented as

_maxusers:	.word 0
		chmk	$MAXUSERS
		rts

or

maxusers()
{
	return getinterestingkernelnumber(MAXUSERS);
}

is of the utmost indifference to me, and I suspect to everyone else.
(Ed wasn't explicit in his posting about which of these he had
chosen.  Nor is there any reason he should have been).

Now, why "must" it be a new function?  Why don't C programmers
just use "getinterestingkernelnumber" and save the overhead of
the extra function call?

Well, there are dozens of reasons, some concerned with modularity,
etc, some with allowing the implementation to then choose which
of the above implementation methods to use (and perhaps, on
the cpu I described above, there'll be a "maxusers" register
that programs can read, so to upgrade an 8 user system to a 16
user system its a hardware strapping - and maxusers wouldn't be
a kernel call at all :-)

You might even make noises along the lines of "performing
one function well"...

The one I like best at the minute, is that if a program that uses
the "maxusers" sys call is moved to a host that doesn't have this
sys call, its much easier to make a workaround function than it
is if the program used getinterestingkernelnumber directly.

The way that you're likely to discover the use of a facility that
your system doesn't have is when you compile the program and end
up with a "xxx undefined" message from the linker.  Now if "xxx"
is "maxusers" you just write a little function

maxusers()
{
	return (100);
}

or something, link it in, and you're in business.  If "xxx" is
"getinterestingkernelnumber" then you start gazing through the
code (which might be a big job - consider the case where you're
sent .o files in the right object format, ready to link with
your system libraries!) to try and determine which particular
kernel number(s) the program is using, or you try and write a
simulation function that returns something for all the possible
kernel numbers that might be wanted.

Which would you rather do???


So, lets end forever this absurd phobia that some people have with
system call counting.  (Which is NOT the same thing as saying
that some kernel is too big, or does things it shouldn't ...
which can be a valid point of dispute)

One thing that has galled me for ages at usenix conferences is the
occasional talk given by someone who has added some facility
to the kernel, but who "hasn't added any new sys calls".  Recently
this has been particularly noticeable in AT&T talks for some
reason.  Either functionality has been added or it hasn't.
You can argue about whether its worth it or not, but PLEASE forget
all this NONSENSE about numbers of sys calls.

In fact, its time that we abandoned the distinction between
sys calls and other C library functions completely (that is
between section 2 and section 3), either something is available
to the user level programmer in some lib func, or its not.

Well, this has gone on far too long now, so I'll cease here.
This has eased my conscience a bit, on occasions recently I've
been tempted to rebut some of the absurdity pronounced by
some "experts" in this forum, but have resisted out of courtesy
to the net - without feeling good about allowing misused
cliches go unchallenged.  Now I feel better.  I hope that
you don't feel I've abused the net too much.

If you have stayed with me this long, I thank you, you can now
go onto more boring discussions about ripping off AT&T etc.

Robert Elz				decvax!mulga!kre

ps: its reasonably warm outside today, a total fire ban day
in Victoria (for those of you who know what that means).  I could
probably be arrested for this posting - except I'm indoors :-)

dan@haddock.UUCP (01/30/85)

> This will only work if the login process used actually updates
> utmp. People could get round this by writing their own /bin/login
> without this feature and hey presto no limit!

True, but there's always a way around any restriction (you could disassemble
the kernel and patch it...).  Two points.  First, the owner of the system
is bound by the license agreement that the vendor supplied with the system,
which limits the number of logins permitted.  Any owner permitting more
would be in violation of the agreement.  Second, the login change ensures
that only by becoming super-user can one violate the license restriction; the
owner can (theoretically) make sure that only trusted people can become root.
So this change amounts to making sure that if more than the agreed number of
people can log in at once, someone's violating the law.

Now, suppose the owner of the system loans it to me, and I exploit some bug in
the ATT code to become root and arrange to permit me to log in myself and
all my friends.  Who would be responsible?  I've signed no agreement, and the
owner didn't ask me to limit the number of users because he thought the system
wouldn't let me.  Would ATT be responsible, for having the bug?  Or the vendor?
This is, of course, a purely hypothetical question, since no such bug exists :-)

Ron Natalie <ron@BRL-TGR> (01/31/85)

I don't think anyone expected the user limit for binary licenses to be
foolproof.  Hence machines are licensed for the number of users they can
be expected to support.  I.e., while an IBM-PC may be a single user machine
(who would want to run multi-user), I doubt I could convice someone to sell
me a single-user license for my Gould PN9000 Firebreather.

-Ron