Linux Kernel Architecture

(Jacob Rumans) #1

Chapter 1: Introduction and Overview


Usually I start my discussion with a general overview about the concepts of the topic that I am going
to present, and then go down to data structures and their interrelation in the kernel. Code is usually
discussed last, because this requires the highest level of detail. I have chosen thistop-downapproach
because it is in our opinion the most accessible and easiest way to understand the kernel. Notice that it
would also be possible to discuss things from the bottom up, that is, start deep down in the kernel and
then work slowly up to the C library and userspace level. Notice, however, that presenting something
in inverse order does not automatically make itbetter. In my experience, more forward references are
required for a bottom-up than for a top-down strategy, so I stick to the latter throughout this book.

When I directly present C source code, I sometimes take the liberty to rewrite it slightly to highlight more
important elements and remove less important ‘‘due diligence’’ work. For example, it is very important
for the kernel to check the return value of every memory allocation. While allocationswillsucceed in
nearly almost all cases, it is essential to take care of cases in which not enough memory is available for a
particular task. The kernel has to deal with this situation somehow, usually by returning an error return
code to userspace if a task is performed as a response to a request by an application, or by omitting a
warning message to the system log. However, details of this kind will in general obstruct the view of
what is really important. Consider the following code, which sets up namespaces for a process:

kernel/nsproxy.c
static struct nsproxy *create_new_namespaces(unsigned long flags,
struct task_struct *tsk, struct fs_struct *new_fs)
{
struct nsproxy *new_nsp;
int err;

new_nsp = clone_nsproxy(tsk->nsproxy);
if (!new_nsp)
return ERR_PTR(-ENOMEM);

new_nsp->mnt_ns = copy_mnt_ns(flags, tsk->nsproxy->mnt_ns, new_fs);
if (IS_ERR(new_nsp->mnt_ns)) {
err = PTR_ERR(new_nsp->mnt_ns);
goto out_ns;
}

new_nsp->uts_ns = copy_utsname(flags, tsk->nsproxy->uts_ns);
if (IS_ERR(new_nsp->uts_ns)) {
err = PTR_ERR(new_nsp->uts_ns);
goto out_uts;
}

new_nsp->ipc_ns = copy_ipcs(flags, tsk->nsproxy->ipc_ns);
if (IS_ERR(new_nsp->ipc_ns)) {
err = PTR_ERR(new_nsp->ipc_ns);
goto out_ipc;
}
...
return new_nsp;
out_ipc:
if (new_nsp->uts_ns)
put_uts_ns(new_nsp->uts_ns);
out_uts:
if (new_nsp->mnt_ns)
Free download pdf