This interface is how the a process can actually set its vpid.  If the
process is in anything other than the default (container 0), whatever
number is written into this file will get returned from getpid().

Right now, there's nothing to stop collisions with different processes
in the same container setting the same pid.  (implementation detail :)

---

 linux-2.6.14-rc5-dave/fs/proc/base.c        |   59 ++++++++++++++++++++++++++++
 linux-2.6.14-rc5-dave/include/linux/sched.h |    1 
 2 files changed, 60 insertions(+)

diff -puN fs/proc/base.c~C2-proc-interface-to-set_vpid fs/proc/base.c
--- linux-2.6.14-rc5/fs/proc/base.c~C2-proc-interface-to-set_vpid       
2005-10-24 17:55:40.000000000 +0200
+++ linux-2.6.14-rc5-dave/fs/proc/base.c        2005-10-24 17:55:40.000000000 
+0200
@@ -166,6 +166,8 @@ enum pid_directory_inos {
        PROC_TID_OOM_ADJUST,
        PROC_TID_CHILD_CONTAINER_ID,
        PROC_TGID_CHILD_CONTAINER_ID,
+       PROC_TGID_VPID,
+       PROC_TID_VPID,
 
        /* Add new entries before this */
        PROC_TID_FD_DIR = 0x8000,       /* 0x8000-0xffff */
@@ -219,6 +221,7 @@ static struct pid_entry tgid_base_stuff[
        E(PROC_TGID_OOM_SCORE, "oom_score",S_IFREG|S_IRUGO),
        E(PROC_TGID_OOM_ADJUST,"oom_adj", S_IFREG|S_IRUGO|S_IWUSR),
        E(PROC_TGID_CHILD_CONTAINER_ID, "child_container_id", 
S_IFREG|S_IRUGO|S_IWUSR),
+       E(PROC_TGID_VPID,       "vpid", S_IFREG|S_IRUGO|S_IWUSR),
 #ifdef CONFIG_AUDITSYSCALL
        E(PROC_TGID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),
 #endif
@@ -262,6 +265,7 @@ static struct pid_entry tid_base_stuff[]
        E(PROC_TID_OOM_SCORE,  "oom_score",S_IFREG|S_IRUGO),
        E(PROC_TID_OOM_ADJUST, "oom_adj", S_IFREG|S_IRUGO|S_IWUSR),
        E(PROC_TID_CHILD_CONTAINER_ID, "child_container_id", 
S_IFREG|S_IRUGO|S_IWUSR),
+       E(PROC_TID_VPID,       "vpid", S_IFREG|S_IRUGO|S_IWUSR),
 #ifdef CONFIG_AUDITSYSCALL
        E(PROC_TID_LOGINUID, "loginuid", S_IFREG|S_IWUSR|S_IRUGO),
 #endif
@@ -964,6 +968,57 @@ static struct file_operations proc_child
        .write          = proc_child_container_id_write,
 };
 
+static ssize_t proc_vpid_read(struct file *file, char __user *buf,
+                               size_t count, loff_t *ppos)
+{
+       struct task_struct *task = proc_task(file->f_dentry->d_inode);
+       char buffer[8];
+       size_t len;
+       int vpid = task->vpid;
+       loff_t __ppos = *ppos;
+
+       len = sprintf(buffer, "%i\n", vpid);
+       if (__ppos >= len)
+               return 0;
+       if (count > len-__ppos)
+               count = len-__ppos;
+       if (copy_to_user(buf, buffer + __ppos, count))
+               return -EFAULT;
+       *ppos = __ppos + count;
+       return count;
+}
+
+extern int pid_max;
+static ssize_t proc_vpid_write(struct file *file, const char __user *buf,
+                               size_t count, loff_t *ppos)
+{
+       struct task_struct *task = proc_task(file->f_dentry->d_inode);
+       char buffer[8], *end;
+       int vpid;
+
+       if (!capable(CAP_SYS_RESOURCE))
+               return -EPERM;
+       memset(buffer, 0, 8);
+       if (count > 6)
+               count = 6;
+       if (copy_from_user(buffer, buf, count))
+               return -EFAULT;
+       vpid = simple_strtol(buffer, &end, 0);
+       if (vpid < 0 || vpid > pid_max)
+               return -EINVAL;
+       if (*end == '\n')
+               end++;
+       task->vpid = vpid;
+       if (end - buffer == 0)
+               return -EIO;
+       return end - buffer;
+}
+
+static struct file_operations proc_vpid_operations = {
+       .read           = proc_vpid_read,
+       .write          = proc_vpid_write,
+};
+
 static struct inode_operations proc_mem_inode_operations = {
        .permission     = proc_permission,
 };
@@ -1806,6 +1861,10 @@ static struct dentry *proc_pident_lookup
                case PROC_TGID_CHILD_CONTAINER_ID:
                        inode->i_fop = &proc_child_container_id_operations;
                        break;
+               case PROC_TID_VPID:
+               case PROC_TGID_VPID:
+                       inode->i_fop = &proc_vpid_operations;
+                       break;
 #ifdef CONFIG_AUDITSYSCALL
                case PROC_TID_LOGINUID:
                case PROC_TGID_LOGINUID:
diff -puN include/linux/sched.h~C2-proc-interface-to-set_vpid 
include/linux/sched.h
--- linux-2.6.14-rc5/include/linux/sched.h~C2-proc-interface-to-set_vpid        
2005-10-24 17:55:40.000000000 +0200
+++ linux-2.6.14-rc5-dave/include/linux/sched.h 2005-10-24 17:55:40.000000000 
+0200
@@ -728,6 +728,7 @@ struct task_struct {
        gid_t gid,egid,sgid,fsgid;
 #define MAX_CONTAINER_ID 1024
        int child_container_id;
+       int vpid;
        struct group_info *group_info;
        kernel_cap_t   cap_effective, cap_inheritable, cap_permitted;
        unsigned keep_capabilities:1;
_
_______________________________________________
Vserver mailing list
Vserver@list.linux-vserver.org
http://list.linux-vserver.org/mailman/listinfo/vserver

Reply via email to