Cómo crear múltiples espacios de nombres de red desde una sola instancia de proceso

Estoy usando la siguiente función C para crearmúltiples espacios de nombres de red a partir de unainstancia de proceso único:

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

Después de que mi proceso crea todos los espacios de nombres y añado ungrifo interfaz a cualquiera del espacio de nombres de una red (conip link set tap1 netns ns1 comando), entonces realmente veo esta interfaz en todos los espacios de nombres (presumiblemente, esto es en realidad un solo espacio de nombres que va con nombres diferentes).

Pero, si creo múltiples espacios de nombres utilizando múltiples procesos, entonces todo está funcionando bien.

¿Qué podría estar mal aquí? ¿Tengo que pasar alguna bandera adicional a launshare() ¿Para que esto funcione desde una sola instancia de proceso? ¿Existe una limitación de que una sola instancia de proceso no pueda crear múltiples espacios de nombres de red? O hay un problema conmount() llamar, porque/proc/self/ns/net en realidad se monta varias veces?

Actualizar: Parece queunshare() La función crea múltiples espacios de nombres de red correctamente, pero todos los puntos de montaje en/var/run/netns/ en realidad, haga referencia al primer espacio de nombres de red que se montó en esa direcotry.

Actualización2: Parece que el mejor enfoque es dividir () otro proceso y ejecutar la función create_namespace () desde allí. De todos modos, me encantaría escuchar una mejor solución que no implique fork () o al menos obtener una confirmación que demuestre que es imposible crear y administrar múltiples espacios de nombres de red desde un solo proceso.

Update3: Puedo crear múltiples espacios de nombres con unshare () usando el siguiente código:

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

Pero una vez finalizado el proceso y ejecutoip netns exec a ifconfig -a yip netns exec b ifconfig -a Parece que ambos comandos se ejecutaron de repente en el espacio de nombresa. Así que el problema real es almacenar las referencias a los espacios de nombres (o llamar a mount () de la manera correcta. Pero no estoy seguro, si esto es posible).

Respuestas a la pregunta(2)

Su respuesta a la pregunta