I'll try and answer both this and your earlier question as they are related.
The doors to namespaces are files in /proc/*/ns/*
and /proc/*/task/*/ns/*
.
A namespace is created by a process unsharing its namespace. A namespace can then be made permanent by bind-mounting the ns
file to some other place.
That's what ip netns
does for instance for net namespaces. It unshares its net
namespace and bind-mounts /proc/self/ns/net
to /run/netns/netns-name
.
In a /proc
mounted in the root pid namespace, you can list all the namespaces that have a process in them by doing:
# readlink /proc/*/task/*/ns/* | sort -u
ipc:[4026531839]
mnt:[4026531840]
mnt:[4026531856]
mnt:[4026532469]
net:[4026531956]
net:[4026532375]
pid:[4026531836]
pid:[4026532373]
uts:[4026531838]
The number in square brackets is the inode number.
To get that for a given process:
# ls -Li /proc/1/ns/pid
4026531836 /proc/1/ns/pid
Now, there may be permanent namespaces that don't have any process in them. Finding them out can be a lot trickier AFAICT.
First, you have to bear in mind that there can be several mount namespaces.
# awk '$9 == "proc" {print FILENAME,$0}' /proc/*/task/*/mountinfo | sort -k2 -u
/proc/1070/task/1070/mountinfo 15 19 0:3 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
/proc/19877/task/19877/mountinfo 50 49 0:3 / /run/netns/a rw,nosuid,nodev,noexec,relatime shared:2 - proc proc rw
/proc/19877/task/19877/mountinfo 57 40 0:3 / /proc rw,nosuid,nodev,noexec,relatime - proc proc rw
/proc/1070/task/1070/mountinfo 66 39 0:3 / /run/netns/a rw,nosuid,nodev,noexec,relatime shared:2 - proc proc rw
/proc/19877/task/19877/mountinfo 68 67 0:3 / /mnt/1/a rw,nosuid,nodev,noexec,relatime unbindable - proc proc rw
Those /mnt/1/a
, /run/netns/a
may be namespace files.
We can get an inode number:
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- ls -Li /mnt/1/a
4026532471 /mnt/1/a
But that doesn't tell us much other than it's not in the list computed above.
We can try and enter it as any of the different types:
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- nsenter --pid=/mnt/1/a true
nsenter: reassociate to namespace 'ns/pid' failed: Invalid argument
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- nsenter --mount=/mnt/1/a true
nsenter: reassociate to namespace 'ns/mnt' failed: Invalid argument
# nsenter --mount=/proc/19877/task/19877/ns/mnt -- nsenter --net=/mnt/1/a true
#
OK, that was a net
namespace file.
So it would seem we have a method to list the name spaces: list the ns
directories of all the tasks, then find all the proc
mountpoints in all the /proc/*/task/*/mountinfo
and figure out their type by trying to enter them.
It should be possible to assign eth0
and eth0:1
to different namespaces, but keep in mind there are security implications because you are exposing physical network device to your container.
Because of that, I would just use veth
and bridge
. Create a bridge br0
and bridge it with eth0
device by default. Then configure your lxc container like this:
lxc.network.type=veth
lxc.network.ipv4=192.168.0.200
lxc.network.link=br0
This will have the same result, but you will use a virtual Ethernet interface for the container and you will also be able to access the same network that your LXC host is in because of the bridge.
Best Answer
You don't need to run process in some control groups if you already in certain namespace, instead you have to manipulate with namespaces. All new process in new namespace will «inherit» all control groups related to that namespace.
Moving processes between different namespaces can be done with setns() function or you can use nsenter command from
util-linux
to enter new namespace and then run new tasks in it. All you need is to know PID of process, which already is new namespace, then you can use (in case you want to runlinks
):It's some cheat, because you don't moving processes, you just entered in namespace and running new processes, but with this possibility you can enter in certain NS and then
fork
in it already running in other NS process.