Blame view

ipc/namespace.c 2.54 KB
ae5e1b22f   Pavel Emelyanov   namespaces: move ...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  /*
   * linux/ipc/namespace.c
   * Copyright (C) 2006 Pavel Emelyanov <xemul@openvz.org> OpenVZ, SWsoft Inc.
   */
  
  #include <linux/ipc.h>
  #include <linux/msg.h>
  #include <linux/ipc_namespace.h>
  #include <linux/rcupdate.h>
  #include <linux/nsproxy.h>
  #include <linux/slab.h>
  
  #include "util.h"
  
  static struct ipc_namespace *clone_ipc_ns(struct ipc_namespace *old_ns)
  {
ae5e1b22f   Pavel Emelyanov   namespaces: move ...
17
  	struct ipc_namespace *ns;
ae5e1b22f   Pavel Emelyanov   namespaces: move ...
18
19
  	ns = kmalloc(sizeof(struct ipc_namespace), GFP_KERNEL);
  	if (ns == NULL)
ed2ddbf88   Pierre Peiffer   IPC: make struct ...
20
  		return ERR_PTR(-ENOMEM);
ae5e1b22f   Pavel Emelyanov   namespaces: move ...
21

4d89dc6ab   Nadia Derbey   ipc: scale msgmni...
22
  	atomic_inc(&nr_ipc_ns);
ed2ddbf88   Pierre Peiffer   IPC: make struct ...
23
24
25
  	sem_init_ns(ns);
  	msg_init_ns(ns);
  	shm_init_ns(ns);
ae5e1b22f   Pavel Emelyanov   namespaces: move ...
26

e2c284d8a   Nadia Derbey   ipc: recompute ms...
27
28
29
30
31
32
  	/*
  	 * msgmni has already been computed for the new ipc ns.
  	 * Thus, do the ipcns creation notification before registering that
  	 * new ipcns in the chain.
  	 */
  	ipcns_notify(IPCNS_CREATED);
b6b337ad1   Nadia Derbey   ipc: recompute ms...
33
  	register_ipcns_notifier(ns);
ae5e1b22f   Pavel Emelyanov   namespaces: move ...
34
35
  	kref_init(&ns->kref);
  	return ns;
ae5e1b22f   Pavel Emelyanov   namespaces: move ...
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
  }
  
  struct ipc_namespace *copy_ipcs(unsigned long flags, struct ipc_namespace *ns)
  {
  	struct ipc_namespace *new_ns;
  
  	BUG_ON(!ns);
  	get_ipc_ns(ns);
  
  	if (!(flags & CLONE_NEWIPC))
  		return ns;
  
  	new_ns = clone_ipc_ns(ns);
  
  	put_ipc_ns(ns);
  	return new_ns;
  }
01b8b07a5   Pierre Peiffer   IPC: consolidate ...
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
  /*
   * free_ipcs - free all ipcs of one type
   * @ns:   the namespace to remove the ipcs from
   * @ids:  the table of ipcs to free
   * @free: the function called to free each individual ipc
   *
   * Called for each kind of ipc when an ipc_namespace exits.
   */
  void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
  	       void (*free)(struct ipc_namespace *, struct kern_ipc_perm *))
  {
  	struct kern_ipc_perm *perm;
  	int next_id;
  	int total, in_use;
  
  	down_write(&ids->rw_mutex);
  
  	in_use = ids->in_use;
  
  	for (total = 0, next_id = 0; total < in_use; next_id++) {
  		perm = idr_find(&ids->ipcs_idr, next_id);
  		if (perm == NULL)
  			continue;
  		ipc_lock_by_ptr(perm);
  		free(ns, perm);
  		total++;
  	}
  	up_write(&ids->rw_mutex);
  }
ae5e1b22f   Pavel Emelyanov   namespaces: move ...
82
83
84
85
86
  void free_ipc_ns(struct kref *kref)
  {
  	struct ipc_namespace *ns;
  
  	ns = container_of(kref, struct ipc_namespace, kref);
b6b337ad1   Nadia Derbey   ipc: recompute ms...
87
88
89
90
91
92
93
94
95
  	/*
  	 * Unregistering the hotplug notifier at the beginning guarantees
  	 * that the ipc namespace won't be freed while we are inside the
  	 * callback routine. Since the blocking_notifier_chain_XXX routines
  	 * hold a rw lock on the notifier list, unregister_ipcns_notifier()
  	 * won't take the rw lock before blocking_notifier_call_chain() has
  	 * released the rd lock.
  	 */
  	unregister_ipcns_notifier(ns);
ae5e1b22f   Pavel Emelyanov   namespaces: move ...
96
97
98
99
  	sem_exit_ns(ns);
  	msg_exit_ns(ns);
  	shm_exit_ns(ns);
  	kfree(ns);
4d89dc6ab   Nadia Derbey   ipc: scale msgmni...
100
  	atomic_dec(&nr_ipc_ns);
e2c284d8a   Nadia Derbey   ipc: recompute ms...
101
102
103
104
105
106
  
  	/*
  	 * Do the ipcns removal notification after decrementing nr_ipc_ns in
  	 * order to have a correct value when recomputing msgmni.
  	 */
  	ipcns_notify(IPCNS_REMOVED);
ae5e1b22f   Pavel Emelyanov   namespaces: move ...
107
  }