Re: [RFC] [patch 2/6] [Network namespace] Network device sharing by view

2006-06-18 Thread Al Viro
On Fri, Jun 09, 2006 at 11:02:04PM +0200, [EMAIL PROTECTED] wrote:

 + read_lock(dev_base_lock);
 +
 + for (dev = dev_base; dev; dev = dev-next)
 + if (!strncmp(dev-name, devname, IFNAMSIZ))
 + break;
 +
 + if (!dev) {
 + ret = -ENODEV;
 + goto out;
 + }
 +
 + db = kmalloc(sizeof(*db), GFP_KERNEL);

deadlock.


Besides, holding references to net_device from userland is Not Good(tm).
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] [patch 2/6] [Network namespace] Network device sharing by view

2006-06-11 Thread Andrew Morton
On Fri, 09 Jun 2006 23:02:04 +0200
[EMAIL PROTECTED] wrote:

 +int net_ns_dev_add(const char *devname,
 +struct net_ns_dev_list *devlist)
 +{
 + struct net_ns_dev *db;
 + struct net_device *dev;
 + int ret = 0;
 +
 + read_lock(dev_base_lock);
 +
 + for (dev = dev_base; dev; dev = dev-next)
 + if (!strncmp(dev-name, devname, IFNAMSIZ))
 + break;
 +
 + if (!dev) {
 + ret = -ENODEV;
 + goto out;
 + }
 +
 + db = kmalloc(sizeof(*db), GFP_KERNEL);

sleep-in-spinlock.  Please always test new code with all kernel debugging
options enabled.
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] [patch 2/6] [Network namespace] Network device sharing by view

2006-06-09 Thread dlezcano
Adds to the network namespace a device list view. This view is emptied
when the unshare is done. The view is filled/emptied by a set of
function which can be called by an external module.

Replace-Subject: [Network namespace] Network device sharing by view
Signed-off-by: Daniel Lezcano [EMAIL PROTECTED] 
--
 include/linux/net_ns.h |2 
 include/linux/net_ns_dev.h |   32 +++
 init/version.c |4 
 net/core/Makefile  |2 
 net/core/net_ns_dev.c  |  205 +
 net/net_ns.c   |6 +
 6 files changed, 250 insertions(+), 1 deletion(-)

Index: 2.6-mm/include/linux/net_ns_dev.h
===
--- /dev/null
+++ 2.6-mm/include/linux/net_ns_dev.h
@@ -0,0 +1,32 @@
+#ifndef _LINUX_NET_NS_DEV_H
+#define _LINUX_NET_NS_DEV_H
+
+struct net_device;
+
+struct net_ns_dev {
+   struct list_head list;
+   struct net_device *dev;
+};
+
+struct net_ns_dev_list {
+   struct list_head list;
+   rwlock_t lock;
+};
+
+extern int net_ns_dev_unregister(struct net_device *dev,
+struct net_ns_dev_list *devlist);
+
+extern int net_ns_dev_register(struct net_device *dev,
+  struct net_ns_dev_list *devlist);
+
+extern struct net_device *net_ns_dev_find_by_name(const char *devname,
+ struct net_ns_dev_list 
*devlist);
+extern int net_ns_dev_remove(const char *devname,
+struct net_ns_dev_list *devlist);
+
+extern int net_ns_dev_add(const char *devname,
+ struct net_ns_dev_list *devlist);
+
+extern int free_net_ns_dev(struct net_ns_dev_list *devlist);
+
+#endif
Index: 2.6-mm/include/linux/net_ns.h
===
--- 2.6-mm.orig/include/linux/net_ns.h
+++ 2.6-mm/include/linux/net_ns.h
@@ -4,9 +4,11 @@
 #include linux/kref.h
 #include linux/sched.h
 #include linux/nsproxy.h
+#include linux/net_ns_dev.h
 
 struct net_namespace {
struct kref kref;
+   struct net_ns_dev_list dev_list;
 };
 
 extern struct net_namespace init_net_ns;
Index: 2.6-mm/net/core/net_ns_dev.c
===
--- /dev/null
+++ 2.6-mm/net/core/net_ns_dev.c
@@ -0,0 +1,205 @@
+/*
+ *  net_ns_dev.c - adds namespace netwok device view
+ *
+ *  Copyright (C) 2006 IBM
+ *
+ *  Author: Daniel Lezcano [EMAIL PROTECTED]
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+#include linux/list.h
+#include linux/spinlock.h
+#include linux/netdevice.h
+#include linux/net_ns_dev.h
+
+int free_net_ns_dev(struct net_ns_dev_list *devlist)
+{
+   struct list_head *l, *next;
+   struct net_ns_dev *db;
+   struct net_device *dev;
+
+   write_lock(devlist-lock);
+   list_for_each_safe(l, next, devlist-list) {
+   db = list_entry(l, struct net_ns_dev, list);
+   dev = db-dev;
+   list_del(db-list);
+   dev_put(dev);
+   kfree(db);
+   }
+   write_unlock(devlist-lock);
+
+   return 0;
+}
+
+/*
+ * Remove a device to the namespace network devices list
+ * when registered from a namespace
+ * @dev : network device
+ * @dev_list: network namespace devices
+ * Return ENODEV if the device does not exist,
+ */
+int net_ns_dev_unregister(struct net_device *dev,
+ struct net_ns_dev_list *devlist)
+{
+   struct net_ns_dev *db;
+   struct list_head *l;
+   int ret = -ENODEV;
+
+   write_lock(devlist-lock);
+   list_for_each(l, devlist-list) {
+   db = list_entry(l, struct net_ns_dev, list);
+   if (dev != db-dev)
+   continue;
+
+   list_del(db-list);
+   dev_put(dev);
+   kfree(db);
+   ret = 0;
+   break;
+   }
+   write_unlock(devlist-lock);
+   return ret;
+}
+
+EXPORT_SYMBOL_GPL(net_ns_dev_unregister);
+
+/*
+ * Add a device to the namespace network devices list
+ * when registered from a namespace
+ * @dev : network device
+ * @dev_list: network namespace devices
+ * Return ENOMEM if allocation fails, 0 on success
+ */
+int net_ns_dev_register(struct net_device *dev,
+   struct net_ns_dev_list *devlist)
+{
+   struct net_ns_dev *db;
+
+   db = kmalloc(sizeof(*db), GFP_KERNEL);
+   if (!db)
+   return -ENOMEM;
+
+   write_lock(devlist-lock);
+   dev_hold(dev);
+   db-dev = dev;
+   list_add_tail(db-list, devlist-list);
+   write_unlock(devlist-lock);
+
+   return 0;
+}
+
+EXPORT_SYMBOL_GPL(net_ns_dev_register);
+
+/*
+ * Add a device to the namespace network devices list
+ *