aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/base.c
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2007-10-19 02:40:14 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-19 14:53:40 -0400
commitb488893a390edfe027bae7a46e9af8083e740668 (patch)
treec469a7f99ad01005a73011c029eb5e5d15454559 /fs/proc/base.c
parent3eb07c8c8adb6f0572baba844ba2d9e501654316 (diff)
pid namespaces: changes to show virtual ids to user
This is the largest patch in the set. Make all (I hope) the places where the pid is shown to or get from user operate on the virtual pids. The idea is: - all in-kernel data structures must store either struct pid itself or the pid's global nr, obtained with pid_nr() call; - when seeking the task from kernel code with the stored id one should use find_task_by_pid() call that works with global pids; - when showing pid's numerical value to the user the virtual one should be used, but however when one shows task's pid outside this task's namespace the global one is to be used; - when getting the pid from userspace one need to consider this as the virtual one and use appropriate task/pid-searching functions. [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: nuther build fix] [akpm@linux-foundation.org: yet nuther build fix] [akpm@linux-foundation.org: remove unneeded casts] Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: Alexey Dobriyan <adobriyan@openvz.org> Cc: Sukadev Bhattiprolu <sukadev@us.ibm.com> Cc: Oleg Nesterov <oleg@tv-sign.ru> 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 'fs/proc/base.c')
-rw-r--r--fs/proc/base.c37
1 files changed, 23 insertions, 14 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 21510c9aa89c..db7636041c10 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1937,14 +1937,14 @@ static int proc_self_readlink(struct dentry *dentry, char __user *buffer,
1937 int buflen) 1937 int buflen)
1938{ 1938{
1939 char tmp[PROC_NUMBUF]; 1939 char tmp[PROC_NUMBUF];
1940 sprintf(tmp, "%d", current->tgid); 1940 sprintf(tmp, "%d", task_tgid_vnr(current));
1941 return vfs_readlink(dentry,buffer,buflen,tmp); 1941 return vfs_readlink(dentry,buffer,buflen,tmp);
1942} 1942}
1943 1943
1944static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) 1944static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
1945{ 1945{
1946 char tmp[PROC_NUMBUF]; 1946 char tmp[PROC_NUMBUF];
1947 sprintf(tmp, "%d", current->tgid); 1947 sprintf(tmp, "%d", task_tgid_vnr(current));
1948 return ERR_PTR(vfs_follow_link(nd,tmp)); 1948 return ERR_PTR(vfs_follow_link(nd,tmp));
1949} 1949}
1950 1950
@@ -2316,6 +2316,7 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
2316 struct dentry *result = ERR_PTR(-ENOENT); 2316 struct dentry *result = ERR_PTR(-ENOENT);
2317 struct task_struct *task; 2317 struct task_struct *task;
2318 unsigned tgid; 2318 unsigned tgid;
2319 struct pid_namespace *ns;
2319 2320
2320 result = proc_base_lookup(dir, dentry); 2321 result = proc_base_lookup(dir, dentry);
2321 if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT) 2322 if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT)
@@ -2325,8 +2326,9 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct
2325 if (tgid == ~0U) 2326 if (tgid == ~0U)
2326 goto out; 2327 goto out;
2327 2328
2329 ns = dentry->d_sb->s_fs_info;
2328 rcu_read_lock(); 2330 rcu_read_lock();
2329 task = find_task_by_pid(tgid); 2331 task = find_task_by_pid_ns(tgid, ns);
2330 if (task) 2332 if (task)
2331 get_task_struct(task); 2333 get_task_struct(task);
2332 rcu_read_unlock(); 2334 rcu_read_unlock();
@@ -2343,7 +2345,8 @@ out:
2343 * Find the first task with tgid >= tgid 2345 * Find the first task with tgid >= tgid
2344 * 2346 *
2345 */ 2347 */
2346static struct task_struct *next_tgid(unsigned int tgid) 2348static struct task_struct *next_tgid(unsigned int tgid,
2349 struct pid_namespace *ns)
2347{ 2350{
2348 struct task_struct *task; 2351 struct task_struct *task;
2349 struct pid *pid; 2352 struct pid *pid;
@@ -2351,9 +2354,9 @@ static struct task_struct *next_tgid(unsigned int tgid)
2351 rcu_read_lock(); 2354 rcu_read_lock();
2352retry: 2355retry:
2353 task = NULL; 2356 task = NULL;
2354 pid = find_ge_pid(tgid, &init_pid_ns); 2357 pid = find_ge_pid(tgid, ns);
2355 if (pid) { 2358 if (pid) {
2356 tgid = pid->nr + 1; 2359 tgid = pid_nr_ns(pid, ns) + 1;
2357 task = pid_task(pid, PIDTYPE_PID); 2360 task = pid_task(pid, PIDTYPE_PID);
2358 /* What we to know is if the pid we have find is the 2361 /* What we to know is if the pid we have find is the
2359 * pid of a thread_group_leader. Testing for task 2362 * pid of a thread_group_leader. Testing for task
@@ -2393,6 +2396,7 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
2393 struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode); 2396 struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode);
2394 struct task_struct *task; 2397 struct task_struct *task;
2395 int tgid; 2398 int tgid;
2399 struct pid_namespace *ns;
2396 2400
2397 if (!reaper) 2401 if (!reaper)
2398 goto out_no_task; 2402 goto out_no_task;
@@ -2403,11 +2407,12 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir)
2403 goto out; 2407 goto out;
2404 } 2408 }
2405 2409
2410 ns = filp->f_dentry->d_sb->s_fs_info;
2406 tgid = filp->f_pos - TGID_OFFSET; 2411 tgid = filp->f_pos - TGID_OFFSET;
2407 for (task = next_tgid(tgid); 2412 for (task = next_tgid(tgid, ns);
2408 task; 2413 task;
2409 put_task_struct(task), task = next_tgid(tgid + 1)) { 2414 put_task_struct(task), task = next_tgid(tgid + 1, ns)) {
2410 tgid = task->pid; 2415 tgid = task_pid_nr_ns(task, ns);
2411 filp->f_pos = tgid + TGID_OFFSET; 2416 filp->f_pos = tgid + TGID_OFFSET;
2412 if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) { 2417 if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) {
2413 put_task_struct(task); 2418 put_task_struct(task);
@@ -2531,6 +2536,7 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry
2531 struct task_struct *task; 2536 struct task_struct *task;
2532 struct task_struct *leader = get_proc_task(dir); 2537 struct task_struct *leader = get_proc_task(dir);
2533 unsigned tid; 2538 unsigned tid;
2539 struct pid_namespace *ns;
2534 2540
2535 if (!leader) 2541 if (!leader)
2536 goto out_no_task; 2542 goto out_no_task;
@@ -2539,8 +2545,9 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry
2539 if (tid == ~0U) 2545 if (tid == ~0U)
2540 goto out; 2546 goto out;
2541 2547
2548 ns = dentry->d_sb->s_fs_info;
2542 rcu_read_lock(); 2549 rcu_read_lock();
2543 task = find_task_by_pid(tid); 2550 task = find_task_by_pid_ns(tid, ns);
2544 if (task) 2551 if (task)
2545 get_task_struct(task); 2552 get_task_struct(task);
2546 rcu_read_unlock(); 2553 rcu_read_unlock();
@@ -2571,14 +2578,14 @@ out_no_task:
2571 * threads past it. 2578 * threads past it.
2572 */ 2579 */
2573static struct task_struct *first_tid(struct task_struct *leader, 2580static struct task_struct *first_tid(struct task_struct *leader,
2574 int tid, int nr) 2581 int tid, int nr, struct pid_namespace *ns)
2575{ 2582{
2576 struct task_struct *pos; 2583 struct task_struct *pos;
2577 2584
2578 rcu_read_lock(); 2585 rcu_read_lock();
2579 /* Attempt to start with the pid of a thread */ 2586 /* Attempt to start with the pid of a thread */
2580 if (tid && (nr > 0)) { 2587 if (tid && (nr > 0)) {
2581 pos = find_task_by_pid(tid); 2588 pos = find_task_by_pid_ns(tid, ns);
2582 if (pos && (pos->group_leader == leader)) 2589 if (pos && (pos->group_leader == leader))
2583 goto found; 2590 goto found;
2584 } 2591 }
@@ -2647,6 +2654,7 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi
2647 ino_t ino; 2654 ino_t ino;
2648 int tid; 2655 int tid;
2649 unsigned long pos = filp->f_pos; /* avoiding "long long" filp->f_pos */ 2656 unsigned long pos = filp->f_pos; /* avoiding "long long" filp->f_pos */
2657 struct pid_namespace *ns;
2650 2658
2651 task = get_proc_task(inode); 2659 task = get_proc_task(inode);
2652 if (!task) 2660 if (!task)
@@ -2680,12 +2688,13 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi
2680 /* f_version caches the tgid value that the last readdir call couldn't 2688 /* f_version caches the tgid value that the last readdir call couldn't
2681 * return. lseek aka telldir automagically resets f_version to 0. 2689 * return. lseek aka telldir automagically resets f_version to 0.
2682 */ 2690 */
2691 ns = filp->f_dentry->d_sb->s_fs_info;
2683 tid = (int)filp->f_version; 2692 tid = (int)filp->f_version;
2684 filp->f_version = 0; 2693 filp->f_version = 0;
2685 for (task = first_tid(leader, tid, pos - 2); 2694 for (task = first_tid(leader, tid, pos - 2, ns);
2686 task; 2695 task;
2687 task = next_tid(task), pos++) { 2696 task = next_tid(task), pos++) {
2688 tid = task->pid; 2697 tid = task_pid_nr_ns(task, ns);
2689 if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) { 2698 if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) {
2690 /* returning this tgid failed, save it as the first 2699 /* returning this tgid failed, save it as the first
2691 * pid for the next readir call */ 2700 * pid for the next readir call */