summaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2008-04-15 09:35:23 +0200
committerDavid S. Miller <davem@davemloft.net>2008-04-15 09:35:23 +0200
commitc93cf61fd1d5378134f9b06703f7078067542e00 (patch)
tree5ea9e584aa2c10b9c395730ee5bb944902d3e760 /net/core
parent[ISDN] include/linux/isdn.h: remove dead code (diff)
downloadlinux-c93cf61fd1d5378134f9b06703f7078067542e00.tar.xz
linux-c93cf61fd1d5378134f9b06703f7078067542e00.zip
[NETNS]: The net-subsys IDs generator.
To make some per-net generic pointers, we need some way to address them, i.e. - IDs. This is simple IDA-based IDs generator for pernet subsystems. Addressing questions about potential checkpoint/restart problems: these IDs are "lite-offsets" within the net structure and are by no means supposed to be exported to the userspace. Since it will be used in the nearest future by devices only (tun, vlan, tunnels, bridge, etc), I make it resemble the functionality of register_pernet_device(). The new ids is stored in the *id pointer _before_ calling the init callback to make this id available in this callback. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/net_namespace.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 7b660834a4c2..2197d51aef3b 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -5,6 +5,7 @@
#include <linux/list.h>
#include <linux/delay.h>
#include <linux/sched.h>
+#include <linux/idr.h>
#include <net/net_namespace.h>
/*
@@ -253,6 +254,8 @@ static void unregister_pernet_operations(struct pernet_operations *ops)
}
#endif
+static DEFINE_IDA(net_generic_ids);
+
/**
* register_pernet_subsys - register a network namespace subsystem
* @ops: pernet operations structure for the subsystem
@@ -330,6 +333,30 @@ int register_pernet_device(struct pernet_operations *ops)
}
EXPORT_SYMBOL_GPL(register_pernet_device);
+int register_pernet_gen_device(int *id, struct pernet_operations *ops)
+{
+ int error;
+ mutex_lock(&net_mutex);
+again:
+ error = ida_get_new_above(&net_generic_ids, 1, id);
+ if (error) {
+ if (error == -EAGAIN) {
+ ida_pre_get(&net_generic_ids, GFP_KERNEL);
+ goto again;
+ }
+ goto out;
+ }
+ error = register_pernet_operations(&pernet_list, ops);
+ if (error)
+ ida_remove(&net_generic_ids, *id);
+ else if (first_device == &pernet_list)
+ first_device = &ops->list;
+out:
+ mutex_unlock(&net_mutex);
+ return error;
+}
+EXPORT_SYMBOL_GPL(register_pernet_gen_device);
+
/**
* unregister_pernet_device - unregister a network namespace netdevice
* @ops: pernet operations structure to manipulate
@@ -348,3 +375,14 @@ void unregister_pernet_device(struct pernet_operations *ops)
mutex_unlock(&net_mutex);
}
EXPORT_SYMBOL_GPL(unregister_pernet_device);
+
+void unregister_pernet_gen_device(int id, struct pernet_operations *ops)
+{
+ mutex_lock(&net_mutex);
+ if (&ops->list == first_device)
+ first_device = first_device->next;
+ unregister_pernet_operations(ops);
+ ida_remove(&net_generic_ids, id);
+ mutex_unlock(&net_mutex);
+}
+EXPORT_SYMBOL_GPL(unregister_pernet_gen_device);