Photo by Morning Brew on Unsplash

Linux Namespaces (part 3/5)

Namespace: UTS

Lukasz
4 min readSep 12, 2020

--

UTS stands for Unix Timesharing System, and NS itself is responsible for “isolating”… hostname (and NIS, but NIS itself has lost his meaning, I believe). It is worth noticing that both a page of man manual and the page in Wikipedia concerning NS do not mention the full name of UTS — so the full name, because of its “little” preciseness (as I suspect), is rather not used.

Let’s create a new UTS namespace:

$ sudo unshare -u

And for greater clarity of the description let’s look at PID, with which our new namespace is “connected”:

(unshare)$ echo $$ 
1234

Namespace inherits the hostname after a parent, so:

(unshare)$ hostname

should give us the same effect as in the superior NS UTS (so in our host system).

Now let’s change the hostname:

(unshare)$ hostname foo

The command hostname in this particular NS will show a new name if in a separate console we check the hostname for our host system (default UTS NS) we will see that it was not changed. Let’s pay our attention to the fact that the “command prompt” in our shell process with PID = 1234 (if “hostname” is visible there) – remains unchanged. But If in our shell with PID = 1234 we start another shell process:

(unshare)$ bash

The command prompt will contain an actual hostname for this NS: “foo”.

Also, if we use the command nsenter for connecting another shell process to this namespace:

$ sudo nsenter -u -t 1234

the command prompt will contain a changed hostname — it’s just that bash (used here) does not update the hostname (in the command prompt) dynamically.

Namespace: Process ID (pid)

Both this one and the next NS (User ID) can be nested and in case of those two NS (PID and User ID) the process of mapping the identifier from superior NS (parent) on the identifier in secondary NS is conducted in the background.

Let’s look at a simple example:

$ sudo unshare -p -f  
(unshare)$ echo $$
1

Pay attention to an additional parameter -f of the command unshare – it is used exclusively in connection with the parameter -p and needed for correct functioning of the process in a newly created namespace (try to skip it and see what will happen at the moment of starting any command in namespace created in such a way) – a detailed explanation of why this parameter is required you can find e.g. here.

The command echo $$ (as we know) returns PID of started shell process – in this case PID = 1!

It seems that everything works fine, but when we execute the command ps it turns out that we see many more processes than we could have expected! However it is the result of how the command ps works – it does not take the information on processes from the current NS, but from the /proc directory! So, from the point of view of ps, nothing changes if in our secondary NS we use the same /proc as in the superior NS (just like in this case).

How to correct this? Let’s use an additional namespace — mnt — and the already tested chroot command.

$ sudo unshare -p -f -m chroot /directory 
(unshare)# mount -t proc proc /proc
(unshare)# echo $$
1
(unshare)# ps ax
PID TTY STAT TIME COMMAND
1 ? S 0:00 /bin/bash -i
4 ? R+ 0:00 ps ax

Now it is just as it should be! :)

Let’s look at an example of another nesting:

(unshare pid + chroot)# unshare -p -f  
(1) mesg: ttyname failed: No such file or directory
(unshare pid + chroot)# echo $$
(2) 1
(unshare pid + chroot)# ps axf
(3) PID TTY STAT TIME COMMAND
1 ? S 0:00 /bin/bash -i
5 ? S 0:00 unshare -p -f
6 ? S 0:00 \_ -bash
11 ? R+ 0:00 \_ ps axf

So in our unshared-and-chrooted environment we create another nesting of PID NS — we can see an error message (1) that can be ignored. (2) A new shell process created in new PID NS has PID = 1 (which is shown by echo command), however the command ps (that we tested) identified this process by the identifier attributed to it in the /proc directory – here as the process with PID = 6 (3).

At the end let’s try to “connect” (using nsenter) to PID NS created by the first (from the previous example) command unshare – first we need to determine PID of the shell process started in this NS:

$ sudo lsns
...
4026532455 mnt 4 27902 root unshare -m -f -p chroot FS_AA
4026532456 pid 2 27903 root /bin/bash -i
...

So PID that interests us is 27903 — now let’s try:

$ sudo nsenter -p -t 27903 
(nsenter)# echo $$
14

Obviously, the nsenter command starts a NEW shell process, that’s why its PID does not equal "1" anymore, but it is still PID that makes sense only in PID NS of the process 27903.

Namespace: User ID (user)

Here I recommend doing your own experiments. The functioning of this NS is similar to PID NS, here we also deal with a possible nesting. Docker and Lxc seem not to use this NS (at least in environments which I had an opportunity to work with).

Namespace: Interprocess Communication (ipc)

NS that let us isolate the system (Linux) structures for inter-process communication (semaphores) — until now I haven’t had an opportunity to use it, so I have no experience in this field — it definitely needs further exploration. :)

<< Linux Namespaces (part 2/5) | Linux Namespaces (part 4/5) >>

--

--