]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
netns: Coexist with the sysfs limitations v2
authorEric W. Biederman <ebiederm@xmission.com>
Tue, 28 Oct 2008 00:51:47 +0000 (17:51 -0700)
committerDavid S. Miller <davem@davemloft.net>
Tue, 28 Oct 2008 00:51:47 +0000 (17:51 -0700)
To make testing of the network namespace simpler allow
the network namespace code and the sysfs code to be
compiled and run at the same time.  To do this only
virtual devices are allowed in the additional network
namespaces and those virtual devices are not placed
in the kobject tree.

Since virtual devices don't actually do anything interesting
hardware wise that needs device management there should
be no loss in keeping them out of the kobject tree and
by implication sysfs.  The gain in ease of testing
and code coverage should be significant.

Changelog:

v2: As pointed out by Benjamin Thery it only makes sense to call
    device_rename in the initial network namespace for now.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Acked-by: Benjamin Thery <benjamin.thery@bull.net>
Tested-by: Serge Hallyn <serue@us.ibm.com>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Acked-by: Daniel Lezcano <dlezcano@fr.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/Kconfig
net/core/dev.c
net/core/net-sysfs.c

index d789d79551ae4207d37e0b386a3db743dde05611..8c3d97ca0d96527f7c0375b5fb3c2ecac56ab3ae 100644 (file)
@@ -27,7 +27,7 @@ menu "Networking options"
 config NET_NS
        bool "Network namespace support"
        default n
-       depends on EXPERIMENTAL && !SYSFS && NAMESPACES
+       depends on EXPERIMENTAL && NAMESPACES
        help
          Allow user space to create what appear to be multiple instances
          of the network stack.
index d9038e328cc153b2257330934bacd78b12e0f3f1..3a2b8be9e67b6780cf2180e2f1ae338c821cc8f2 100644 (file)
@@ -924,10 +924,15 @@ int dev_change_name(struct net_device *dev, const char *newname)
                strlcpy(dev->name, newname, IFNAMSIZ);
 
 rollback:
-       ret = device_rename(&dev->dev, dev->name);
-       if (ret) {
-               memcpy(dev->name, oldname, IFNAMSIZ);
-               return ret;
+       /* For now only devices in the initial network namespace
+        * are in sysfs.
+        */
+       if (net == &init_net) {
+               ret = device_rename(&dev->dev, dev->name);
+               if (ret) {
+                       memcpy(dev->name, oldname, IFNAMSIZ);
+                       return ret;
+               }
        }
 
        write_lock_bh(&dev_base_lock);
@@ -4460,6 +4465,15 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
        if (dev->features & NETIF_F_NETNS_LOCAL)
                goto out;
 
+#ifdef CONFIG_SYSFS
+       /* Don't allow real devices to be moved when sysfs
+        * is enabled.
+        */
+       err = -EINVAL;
+       if (dev->dev.parent)
+               goto out;
+#endif
+
        /* Ensure the device has been registrered */
        err = -EINVAL;
        if (dev->reg_state != NETREG_REGISTERED)
@@ -4517,6 +4531,8 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
         */
        dev_addr_discard(dev);
 
+       netdev_unregister_kobject(dev);
+
        /* Actually switch the network namespace */
        dev_net_set(dev, net);
 
@@ -4533,7 +4549,6 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
        }
 
        /* Fixup kobjects */
-       netdev_unregister_kobject(dev);
        err = netdev_register_kobject(dev);
        WARN_ON(err);
 
index 92d6b946731430ddb9b5533498bc6e04c104c3c0..85cb8bdcfb8f4feb154d65c34be240eef3a46ba2 100644 (file)
@@ -476,6 +476,10 @@ void netdev_unregister_kobject(struct net_device * net)
        struct device *dev = &(net->dev);
 
        kobject_get(&dev->kobj);
+
+       if (dev_net(net) != &init_net)
+               return;
+
        device_del(dev);
 }
 
@@ -501,6 +505,9 @@ int netdev_register_kobject(struct net_device *net)
 #endif
 #endif /* CONFIG_SYSFS */
 
+       if (dev_net(net) != &init_net)
+               return 0;
+
        return device_add(dev);
 }