Jak utworzyć wiele sieciowych przestrzeni nazw z pojedynczej instancji procesu

Używam następującej funkcji C do tworzeniawiele sieciowych przestrzeni nazw odpojedyncza instancja procesu:

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);
}

Po moim procesie tworzy wszystkie obszary nazw i dodajekran interfejs do dowolnej z jednej przestrzeni nazw sieciowych (za pomocąip link set tap1 netns ns1 polecenie), wtedy faktycznie widzę ten interfejs we wszystkich przestrzeniach nazw (przypuszczalnie jest to pojedyncza przestrzeń nazw, która zawiera różne nazwy).

Ale jeśli tworzę wiele przestrzeni nazw przy użyciu wielu procesów, wszystko działa dobrze.

Co tu może być nie tak? Czy muszę przekazać dodatkowe flagi dounshare() aby to działało z pojedynczej instancji procesu? Czy istnieje ograniczenie, że pojedyncza instancja procesu nie może utworzyć wielu sieciowych przestrzeni nazw? Czy jest problem zmount() zadzwoń, bo/proc/self/ns/net jest zamontowany wiele razy?

Aktualizacja: Wygląda na to żeunshare() funkcja tworzy poprawnie wiele sieciowych przestrzeni nazw, ale wszystkie punkty podłączenia znajdują się w/var/run/netns/ faktycznie odwołuje się do pierwszej sieciowej przestrzeni nazw, która była zamontowana w tym programie.

Aktualizacja 2: Wydaje się, że najlepszym podejściem jest fork () inny proces i stamtąd wykonanie funkcji create_namespace (). W każdym razie byłbym zadowolony słysząc lepsze rozwiązanie, które nie wymaga wywołania fork () lub przynajmniej otrzyma potwierdzenie, które udowodniłoby, że niemożliwe jest utworzenie i zarządzanie wieloma sieciowymi przestrzeniami nazw z jednego procesu.

Aktualizacja3: Jestem w stanie utworzyć wiele przestrzeni nazw za pomocą polecenia unshare (), używając następującego kodu:

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.
}

Ale po zakończeniu procesu i wykonaniuip netns exec a ifconfig -a iip netns exec b ifconfig -a wydaje się, że oba polecenia zostały nagle wykonane w przestrzeni nazwa. Rzeczywistym problemem jest więc przechowywanie odwołań do przestrzeni nazw (lub wywoływanie mount () we właściwy sposób. Ale nie jestem pewien, czy jest to możliwe).

questionAnswers(2)

yourAnswerToTheQuestion