August 2000
sysctl the Command and the SubroutineComing from a hybrid Sys V and BSD system, the first time I
began maintaining a BSD system I was immediately plunged into
making system level changes and finding out very specific
information about the system. There is a tool for just such a task,
sysctl. Along with that, however, I had come across an
unusual program that needed access to such information as well. The
program needed the information "hard coded", something I did not
like. Luckily, the sysctl calls are easily (and
extraordinarily well documented) accessible via a simple system
subroutine. The article will cover two aspects of
sysctl:
sysctl command.sysctl
subroutines.Note: Examples were drawn from all three free BSDs (I have run all three of them at one time or another): NetBSD, FreeBSD and OpenBSD.
sysctl Command (Facility)It might be more correct to call sysctl a
facility or utility rather than just a command.
The official short definition is:
In reality (typical to BSD design - which is a good
thing) sysctl has been extended to a great many things
and show all sorts of great information. I say this because judging
by the short definition, one would think all you can do with it is
examine kernel parameters and perhaps modify others . . . well,
that and:
Really, the well documented man page of man 8
sysctl has all the information you need. Let us take a look
at some sample usages:
First, how about the OS type:
$ sysctl kern.ostype kern.ostype = NetBSD
Here is a sample looking at the clockrate:
$ sysctl kern.clocktrate kern.clockrate = tick = 10000, tickadj = 40, hz = 100, profhz = 100, stathz = 100
A very important (and often modified parameter on systems) ye olde ip forwarding (where 1 is on and 0 is off):
$ sysctl net.inet.ip.forwarding net.inet.ip.forwarding = 0
Now some real quick hardware gathering examples that show us the following information respectfully:
$ sysctl kern.hw.machine hw.machine = sparc $sysctl hw.model hw.model = SUNW,SPARCstation-5, MB86904 @ 110 MHz, on-chip FPU $ sysctl hw.ncpu hw.ncpu = 1
Another quick note: all of the examples were done in userland.
We have seen the ease of use of the sysctl command,
but the subroutine offers great access at a low level to even more
information.
sysctl Subroutine(s)Note: The next section requires a basic understanding the C programming language.
The sysctl function allows programmatic access to a
wide array of information about the system itself, the kernel and
network information, in this respect it is very similar in nature
to it's command counterpart. It should also be quite obvious that
this is in fact the function that the sysctl primarily
uses (duh). Why is it important to know
or understand? The name of the game is understanding, seeing how to
directly access the sysctl function is one of
the many steps to understanding systems programming.
Additionally, using the function can help develop or
extend utilities. The reason sysctl is so wonderful at
this is how it is so linked to the core operating system. I
must reiterate the BSD philosophy of extension versus new. It is
better to extend a pre-existing piece of software rather than
encourage the development of a completely new one, nevertheless,
the sysctl function could be useful for (and is no
doubt in employed in many other pieces of existing programs)
building new utilities.
Well let us get to it shall we? For the sake of simplicity, the code examples will follow some of the examples shown in the command section of this article. The best way to illustrate a usage is a case study, so. let us create one, for posterity, we will acknowledge the great forecoders by using the example that comes from the BSD Programmer's Manual and an additional one that does not:
We have a program that, for some odd reason, needs to know the following information:
- the number of processes allowed on the system (the one from the manual)
- the number of cpus (perhaps 3rd party licensing software )
One thing I believe in is paying due respect and as such, we will peruse one of the examples in the BSD documentation, how to snag the number of processes allowed on the system:
. . .
#include <sys/sysctl.h>
. . .
int get_processes_max {
int mib[2], maxproc;
size_t len;
mib[0] = CTL_KERN;
mib[1] = KERN_MAXPROC;
len = sizeof(maxproc);
sysctl(mib, 2, &maxproc, &len, NULL, 0);
return maxproc;
}
It is important, at this point, to understand what it is we are accessing and how it is done. To think in C terms, we are looking at it (again, noted in the man page):
int sysctl(int *name, y_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
If you look carefully across the function prototype for
sysctl you will see where all of the arguments
specified satisy the function.
Again, for the next value, our function really would not have to look much different:
. . .
#include <sys/sysctl.h>
. . .
int get_processes_max {
int mib[2], num_cpu;
size_t len;
mib[0] = CTL_HW;
mib[1] = HW_NCPU;
len = sizeof(num_cpu);
sysctl(mib, 2, &num_cpu, &len, NULL, 0);
return num_cpu;
}
Basically what we are looking at is access to data structures, nothing more really. The great thing about it is the ease of access, quite simpler than endless routine writing for endless direct file level access, instead, using this function, we can get a great deal of information about the system with a minimal and safe level of exertion.
BSD presents an unparalled opportunity to delve into the inner workings of BSD and UNIX itself. Continue on and look to programming guides and documentation to lead the way, you will not be disappointed.
(based on last 2 months log reports)