Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 10: Filesystems without Persistent Storage


Thecoreofthecodeisthesysctlfunction defined by the C standard library in/usr/include/
sys/sysctl.h:


int sysctl (int *names, int nlen, void *oldval,
size_t *oldlenp, void *newval, size_t newlen)

The path to the sysctl is given as an integer array in which each array element represents a path compo-
nent. In our example, the path is defined statically innames.


The kernel does not know how many path components there are and must therefore be informed explic-
itly by means ofnlen; there are three components in our example.


oldvalis a pointer to a memory area of undefined type, andoldlenpspecifies the size of the reserved
area in bytes. The kernel uses theoldvalpointer to return the old value represented by sysctl. If this
information can be read but not manipulated, its value is the same both before and after the sysctl call.
In this case,oldvalis used to read its value. Once the system call has been executed, the length of the
output data is given inoldval; for this reason, the variable must be passed by reference and not by value.


newvalandnewlenalso form a pair consisting of a pointer and a length specification. They are used when
a sysctl allows a kernel parameter to be modified. Thenewvalpointer points to the memory area where
the new information is held in userspace, andnewlenpspecifies its length. A null pointer is passed for
newvaland a zero fornewlenpin the case of read access, as in our example.


How does the sample code work? Once all parameters have been generated for thesysctlcall (path-
name and memory location to return the desired information),sysctlis invoked and returns an integer
number as its result. 0 means that the call was successful (I skip error handling for the sake of simplicity).
The data obtained are held inoldvaland can be printed out like any normal C string usingprintf.


Data Structures


The kernel defines several data structures for managing sysctls. As usual, let’s take a closer look at them
before examining their implementation. Because sysctls are arranged hierarchically (each larger kernel
subsystem defines its own sysctl list with its various subsections), the data structure must not only hold
information on the individual sysctls and their read and write operations, it must also provide ways of
mapping the hierarchy between the individual entries.


Each sysctl entry has its ownctl_tableinstance:


<sysctl.h>
struct ctl_table
{
int ctl_name; /* Binary ID */
const char *procname; /* Text ID for /proc/sys, or zero */
void *data;
int maxlen;
mode_t mode;
struct ctl_table *child;
struct ctl_table *parent; /* Automatically set */
proc_handler *proc_handler; /* Callback for text formatting */
ctl_handler *strategy; /* Callback function for all r/w */
Free download pdf