August 2000

Using sysctl the Command and the Subroutine

Coming 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:

  1. Some examples using the sysctl command.
  2. Examples with sample code on using the 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.

The 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:

sysctl
get or set kernel state

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:

  • get specific hardware information
  • get and set a wide variety of kernel level network parameters
  • get and set dependancy information
  • . . . and the list goes on

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:

  1. machine type
  2. specific model information
  3. number of processors
   $ 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.

Using the 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 )

Getting the Number of Processes

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.

Just The Beginning

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.