Я использую следующую функцию C, чтобы создать несколько пространств имен из одного экземпляра процесса:
void create_namespace(const char *ns_name)
{
char ns_path[100];
snprintf(ns_path, 100, "%s/%s", "/var/run/netns", ns_name);
close(open(ns_path, O_RDONLY|O_CREAT|O_EXCL, 0));
unshare(CLONE_NEWNET);
mount("/proc/self/ns/net", ns_path, "none", MS_BIND , NULL);
}
После того, как мой процесс создает все пространства имен, и я добавляю интерфейс крана в любое из одного сетевого пространства имен (с помощью команды ip link set tap1 netns ns1
), тогда я действительно вижу этот интерфейс во всех пространствах имен (предположительно, это на самом деле один пространство имен, которое под разными именами).
Но, если я создаю несколько пространств имен, используя несколько процессов, все работает отлично.
Что здесь может быть неправильным? Должен ли я передавать какие-либо дополнительные флаги в unshare()
, чтобы заставить это работать из одного экземпляра процесса? Есть ли ограничение на то, что один экземпляр процесса не может создавать несколько пространств имен в сети? Или существует проблема с вызовом mount()
, потому что /proc/self/ns/net
фактически установлен несколько раз?
Update:
Кажется, что функция unshare()
создает несколько пространств имен в сети правильно, но все точки монтирования в /var/run/netns/
фактически ссылаются на первое пространство имен в сети, которое было установлено в этом указателе.
Update2: Кажется, что лучший подход заключается в fork() другом процессе и выполнении функции create_namespace(). Во всяком случае, я был бы рад услышать лучшее решение, которое не связано с вызовом fork(), или, по крайней мере, получить подтверждение, которое докажет, что невозможно создать и управлять несколькими пространством имен из одного процесса.
Update3: Я могу создать несколько пространств имен с unshare(), используя следующий код:
int main() {
create_namespace("a");
system("ip tuntap add mode tap tapa");
system("ifconfig -a");//shows lo and tapA interface
create_namespace("b");
system("ip tuntap add mode tap tapb");
system("ifconfig -a");//show lo and tapB interface, but does not show tapA. So this is second namespace created.
}
Но после завершения процесса и выполнения ip netns exec a ifconfig -a
и ip netns exec b ifconfig -a
кажется, что обе команды были внезапно выполнены в пространстве имен a. Поэтому актуальной проблемой является сохранение ссылок на пространства имен (или правильное обращение к mount(). Но я не уверен, если это возможно).