Chapter 2: Process Management and Scheduling
.machine = UTS_MACHINE,
.domainname = UTS_DOMAINNAME,
},
};
The pre-processor constants are defined on various places across the kernel.UTS_RELEASEis, for instance,
set in<utsrelease.h>, which is dynamically generated at build time by the top-levelMakefile.
Notice that some parts of the UTS structure cannot be changed. For instance, it would not make sense to
exchangesysnameby anything else thanLinux. It is, however, possible to change themachinename, for
example.
How does the kernel go about creating a new UTS namespace? This falls under the responsibility of
the functioncopy_utsname. The function is called when a process is forked and the flagCLONE_NEWUTS
specifies that a new UTS namespace is to be established. In this case, a copy of the previous instance
ofuts_namespaceis generated, and a corresponding pointer is installed into thensproxyinstance of the
current task. Nothing more is required! Since the kernel makes sure to always operate on the task-specific
uts_namespaceinstance whenever a UTS value is read or set, changes for the current process will not be
reflected in the parent, and changes in the parent will also not propagate toward the children.
The User Namespace
The user namespace is handled similarly in terms of data structure management: When a new user
namespace is requested, a copy of the current user namespace is generated and associated with the
nsproxyinstance of the current task. However, the representation of a user namespace itself is slightly
more complex:
<user_namespace.h>
struct user_namespace {
struct kref kref;
struct hlist_head uidhash_table[UIDHASH_SZ];
struct user_struct *root_user;
};
As before,krefis a reference counter that tracks in how many places auser_namespaceinstance is
required. For each user in the namespace, an instance ofstruct user_structkeeps track of the individ-
ual resource consumption, and the individual instances are accessible via the hash tableuidhash_table.
The exact definition ofuser_structis not interesting for our purposes. It suffices to know that some sta-
tistical elements like the number of open files or processes a user has are kept in there. What is much more
interesting is that each user namespace accounts resource usage for its users completely detached from
other namespaces — including accounting for the root user. This is possible because a newuser_struct
both for the current user and the root is created when a user namespace is cloned:
kernel/user_namespace.c
static struct user_namespace *clone_user_ns(struct user_namespace *old_ns)
{
struct user_namespace *ns;
struct user_struct *new_user;
...
ns = kmalloc(sizeof(struct user_namespace), GFP_KERNEL);
...