aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2007-10-19 02:40:06 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-19 14:53:39 -0400
commit198fe21b0a17fe9c68cb519ecc566534b04f122b (patch)
tree690825669858d0f458fc137e42adf77cdf370ea4 /kernel
parent7af5729474b5b8ad385adadab78d6e723e7655a3 (diff)
pid namespaces: helpers to find the task by its numerical ids
When searching the task by numerical id on may need to find it using global pid (as it is done now in kernel) or by its virtual id, e.g. when sending a signal to a task from one namespace the sender will specify the task's virtual id and we should find the task by this value. [akpm@linux-foundation.org: fix gfs2 linkage] Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Cc: Oleg Nesterov <oleg@tv-sign.ru> Cc: Sukadev Bhattiprolu <sukadev@us.ibm.com> Cc: Paul Menage <menage@google.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/pid.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/kernel/pid.c b/kernel/pid.c
index 6eb14841b734..a2b4cbbdd63d 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -71,6 +71,7 @@ struct pid_namespace init_pid_ns = {
71 .level = 0, 71 .level = 0,
72 .child_reaper = &init_task, 72 .child_reaper = &init_task,
73}; 73};
74EXPORT_SYMBOL_GPL(init_pid_ns);
74 75
75int is_global_init(struct task_struct *tsk) 76int is_global_init(struct task_struct *tsk)
76{ 77{
@@ -210,7 +211,8 @@ fastcall void free_pid(struct pid *pid)
210 unsigned long flags; 211 unsigned long flags;
211 212
212 spin_lock_irqsave(&pidmap_lock, flags); 213 spin_lock_irqsave(&pidmap_lock, flags);
213 hlist_del_rcu(&pid->pid_chain); 214 for (i = 0; i <= pid->level; i++)
215 hlist_del_rcu(&pid->numbers[i].pid_chain);
214 spin_unlock_irqrestore(&pidmap_lock, flags); 216 spin_unlock_irqrestore(&pidmap_lock, flags);
215 217
216 for (i = 0; i <= pid->level; i++) 218 for (i = 0; i <= pid->level; i++)
@@ -225,6 +227,7 @@ struct pid *alloc_pid(struct pid_namespace *ns)
225 enum pid_type type; 227 enum pid_type type;
226 int i, nr; 228 int i, nr;
227 struct pid_namespace *tmp; 229 struct pid_namespace *tmp;
230 struct upid *upid;
228 231
229 pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL); 232 pid = kmem_cache_alloc(ns->pid_cachep, GFP_KERNEL);
230 if (!pid) 233 if (!pid)
@@ -251,7 +254,11 @@ struct pid *alloc_pid(struct pid_namespace *ns)
251 INIT_HLIST_HEAD(&pid->tasks[type]); 254 INIT_HLIST_HEAD(&pid->tasks[type]);
252 255
253 spin_lock_irq(&pidmap_lock); 256 spin_lock_irq(&pidmap_lock);
254 hlist_add_head_rcu(&pid->pid_chain, &pid_hash[pid_hashfn(pid->nr, ns)]); 257 for (i = ns->level; i >= 0; i--) {
258 upid = &pid->numbers[i];
259 hlist_add_head_rcu(&upid->pid_chain,
260 &pid_hash[pid_hashfn(upid->nr, upid->ns)]);
261 }
255 spin_unlock_irq(&pidmap_lock); 262 spin_unlock_irq(&pidmap_lock);
256 263
257out: 264out:
@@ -266,19 +273,20 @@ out_free:
266 goto out; 273 goto out;
267} 274}
268 275
269struct pid * fastcall find_pid(int nr) 276struct pid * fastcall find_pid_ns(int nr, struct pid_namespace *ns)
270{ 277{
271 struct hlist_node *elem; 278 struct hlist_node *elem;
272 struct pid *pid; 279 struct upid *pnr;
280
281 hlist_for_each_entry_rcu(pnr, elem,
282 &pid_hash[pid_hashfn(nr, ns)], pid_chain)
283 if (pnr->nr == nr && pnr->ns == ns)
284 return container_of(pnr, struct pid,
285 numbers[ns->level]);
273 286
274 hlist_for_each_entry_rcu(pid, elem,
275 &pid_hash[pid_hashfn(nr, &init_pid_ns)], pid_chain) {
276 if (pid->nr == nr)
277 return pid;
278 }
279 return NULL; 287 return NULL;
280} 288}
281EXPORT_SYMBOL_GPL(find_pid); 289EXPORT_SYMBOL_GPL(find_pid_ns);
282 290
283/* 291/*
284 * attach_pid() must be called with the tasklist_lock write-held. 292 * attach_pid() must be called with the tasklist_lock write-held.
@@ -338,12 +346,13 @@ struct task_struct * fastcall pid_task(struct pid *pid, enum pid_type type)
338/* 346/*
339 * Must be called under rcu_read_lock() or with tasklist_lock read-held. 347 * Must be called under rcu_read_lock() or with tasklist_lock read-held.
340 */ 348 */
341struct task_struct *find_task_by_pid_type(int type, int nr) 349struct task_struct *find_task_by_pid_type_ns(int type, int nr,
350 struct pid_namespace *ns)
342{ 351{
343 return pid_task(find_pid(nr), type); 352 return pid_task(find_pid_ns(nr, ns), type);
344} 353}
345 354
346EXPORT_SYMBOL(find_task_by_pid_type); 355EXPORT_SYMBOL(find_task_by_pid_type_ns);
347 356
348struct pid *get_task_pid(struct task_struct *task, enum pid_type type) 357struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
349{ 358{
@@ -370,7 +379,7 @@ struct pid *find_get_pid(pid_t nr)
370 struct pid *pid; 379 struct pid *pid;
371 380
372 rcu_read_lock(); 381 rcu_read_lock();
373 pid = get_pid(find_pid(nr)); 382 pid = get_pid(find_vpid(nr));
374 rcu_read_unlock(); 383 rcu_read_unlock();
375 384
376 return pid; 385 return pid;
@@ -394,15 +403,15 @@ pid_t pid_nr_ns(struct pid *pid, struct pid_namespace *ns)
394 * 403 *
395 * If there is a pid at nr this function is exactly the same as find_pid. 404 * If there is a pid at nr this function is exactly the same as find_pid.
396 */ 405 */
397struct pid *find_ge_pid(int nr) 406struct pid *find_ge_pid(int nr, struct pid_namespace *ns)
398{ 407{
399 struct pid *pid; 408 struct pid *pid;
400 409
401 do { 410 do {
402 pid = find_pid(nr); 411 pid = find_pid_ns(nr, ns);
403 if (pid) 412 if (pid)
404 break; 413 break;
405 nr = next_pidmap(task_active_pid_ns(current), nr); 414 nr = next_pidmap(ns, nr);
406 } while (nr > 0); 415 } while (nr > 0);
407 416
408 return pid; 417 return pid;