diff -NurpP --minimal linux-2.6.0-test11/arch/alpha/kernel/systbls.S linux-2.6.0-test11-vs0.02/arch/alpha/kernel/systbls.S --- linux-2.6.0-test11/arch/alpha/kernel/systbls.S Wed Nov 26 21:44:32 2003 +++ linux-2.6.0-test11-vs0.02/arch/alpha/kernel/systbls.S Fri Dec 12 18:22:36 2003 @@ -291,7 +291,7 @@ sys_call_table: .quad alpha_ni_syscall /* 270 */ .quad alpha_ni_syscall .quad alpha_ni_syscall - .quad alpha_ni_syscall + .quad sys_vserver /* 273 sys_vserver */ .quad alpha_ni_syscall .quad alpha_ni_syscall /* 275 */ .quad alpha_ni_syscall diff -NurpP --minimal linux-2.6.0-test11/arch/i386/kernel/entry.S linux-2.6.0-test11-vs0.02/arch/i386/kernel/entry.S --- linux-2.6.0-test11/arch/i386/kernel/entry.S Wed Nov 26 21:43:26 2003 +++ linux-2.6.0-test11-vs0.02/arch/i386/kernel/entry.S Fri Dec 12 18:21:12 2003 @@ -881,6 +881,6 @@ ENTRY(sys_call_table) .long sys_tgkill /* 270 */ .long sys_utimes .long sys_fadvise64_64 - .long sys_ni_syscall /* sys_vserver */ + .long sys_vserver syscall_table_size=(.-sys_call_table) diff -NurpP --minimal linux-2.6.0-test11/arch/ppc/kernel/misc.S linux-2.6.0-test11-vs0.02/arch/ppc/kernel/misc.S --- linux-2.6.0-test11/arch/ppc/kernel/misc.S Wed Nov 26 21:45:34 2003 +++ linux-2.6.0-test11-vs0.02/arch/ppc/kernel/misc.S Fri Dec 12 18:22:36 2003 @@ -1385,3 +1385,23 @@ _GLOBAL(sys_call_table) .long sys_statfs64 .long sys_fstatfs64 .long ppc_fadvise64_64 + .long sys_ni_syscall /* 255 */ + .long sys_ni_syscall + .long sys_ni_syscall + .long sys_ni_syscall + .long sys_ni_syscall + .long sys_ni_syscall /* 260 */ + .long sys_ni_syscall + .long sys_ni_syscall + .long sys_ni_syscall + .long sys_ni_syscall + .long sys_ni_syscall /* 265 */ + .long sys_ni_syscall + .long sys_ni_syscall + .long sys_ni_syscall + .long sys_ni_syscall + .long sys_ni_syscall /* 270 */ + .long sys_ni_syscall + .long sys_ni_syscall + .long sys_vserver /* 273 sys_vserver */ + diff -NurpP --minimal linux-2.6.0-test11/arch/ppc64/kernel/misc.S linux-2.6.0-test11-vs0.02/arch/ppc64/kernel/misc.S --- linux-2.6.0-test11/arch/ppc64/kernel/misc.S Wed Nov 26 21:45:28 2003 +++ linux-2.6.0-test11-vs0.02/arch/ppc64/kernel/misc.S Fri Dec 12 18:22:36 2003 @@ -852,6 +852,26 @@ _GLOBAL(sys_call_table32) .llong .sys32_utimes .llong .sys_statfs64 .llong .sys_fstatfs64 + .llong .sys_ni_syscall + .llong .sys_ni_syscall /* 255 */ + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall /* 260 */ + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall /* 265 */ + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall /* 270 */ + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_vserver /* 273 sys_vserver */ .balign 8 _GLOBAL(sys_call_table) @@ -1109,3 +1129,24 @@ _GLOBAL(sys_call_table) .llong .sys_utimes .llong .sys_statfs64 .llong .sys_fstatfs64 + .llong .sys_ni_syscall + .llong .sys_ni_syscall /* 255 */ + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall /* 260 */ + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall /* 265 */ + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_ni_syscall /* 270 */ + .llong .sys_ni_syscall + .llong .sys_ni_syscall + .llong .sys_vserver /* 273 sys_vserver */ + diff -NurpP --minimal linux-2.6.0-test11/arch/s390/kernel/syscalls.S linux-2.6.0-test11-vs0.02/arch/s390/kernel/syscalls.S --- linux-2.6.0-test11/arch/s390/kernel/syscalls.S Wed Nov 26 21:42:57 2003 +++ linux-2.6.0-test11-vs0.02/arch/s390/kernel/syscalls.S Fri Dec 12 18:20:12 2003 @@ -271,4 +271,4 @@ SYSCALL(sys_clock_settime,sys_clock_sett SYSCALL(sys_clock_gettime,sys_clock_gettime,sys_ni_syscall) /* 260 */ SYSCALL(sys_clock_getres,sys_clock_getres,sys_ni_syscall) SYSCALL(sys_clock_nanosleep,sys_clock_nanosleep,sys_ni_syscall) -NI_SYSCALL /* reserved for vserver */ +SYSCALL(sys_vserver,sys_vserver,sys_vserver) diff -NurpP --minimal linux-2.6.0-test11/arch/sparc/kernel/systbls.S linux-2.6.0-test11-vs0.02/arch/sparc/kernel/systbls.S --- linux-2.6.0-test11/arch/sparc/kernel/systbls.S Wed Nov 26 21:44:10 2003 +++ linux-2.6.0-test11-vs0.02/arch/sparc/kernel/systbls.S Fri Dec 12 18:16:10 2003 @@ -72,7 +72,7 @@ sys_call_table: /*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl /*255*/ .long sys_nis_syscall, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep /*260*/ .long sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun -/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_io_setup, sys_io_destroy +/*265*/ .long sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy /*270*/ .long sys_io_submit, sys_io_cancel, sys_io_getevents, sys_nis_syscall #ifdef CONFIG_SUNOS_EMUL diff -NurpP --minimal linux-2.6.0-test11/arch/sparc64/kernel/systbls.S linux-2.6.0-test11-vs0.02/arch/sparc64/kernel/systbls.S --- linux-2.6.0-test11/arch/sparc64/kernel/systbls.S Wed Nov 26 21:43:41 2003 +++ linux-2.6.0-test11-vs0.02/arch/sparc64/kernel/systbls.S Fri Dec 12 18:17:12 2003 @@ -72,7 +72,7 @@ sys_call_table32: /*250*/ .word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl .word sys_ni_syscall, compat_clock_settime, compat_clock_gettime, compat_clock_getres, compat_clock_nanosleep /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, compat_timer_settime, compat_timer_gettime, sys_timer_getoverrun - .word sys_timer_delete, sys32_timer_create, sys_ni_syscall, sys_ni_syscall, sys_ni_syscall + .word sys_timer_delete, sys32_timer_create, sys_vserver, sys_ni_syscall, sys_ni_syscall /*270*/ .word sys_ni_syscall, sys_ni_syscall, sys_ni_syscall, sys_ni_syscall /* Now the 64-bit native Linux syscall table. */ @@ -134,7 +134,7 @@ sys_call_table: /*250*/ .word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl .word sys_ni_syscall, sys_clock_settime, sys_clock_gettime, sys_clock_getres, sys_clock_nanosleep /*260*/ .word sys_sched_getaffinity, sys_sched_setaffinity, sys_timer_settime, sys_timer_gettime, sys_timer_getoverrun - .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_io_setup, sys_io_destroy + .word sys_timer_delete, sys_timer_create, sys_vserver, sys_io_setup, sys_io_destroy /*270*/ .word sys_io_submit, sys_io_cancel, sys_io_getevents, sys_ni_syscall #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ diff -NurpP --minimal linux-2.6.0-test11/arch/x86_64/ia32/ia32entry.S linux-2.6.0-test11-vs0.02/arch/x86_64/ia32/ia32entry.S --- linux-2.6.0-test11/arch/x86_64/ia32/ia32entry.S Wed Nov 26 21:43:51 2003 +++ linux-2.6.0-test11-vs0.02/arch/x86_64/ia32/ia32entry.S Fri Dec 12 18:22:36 2003 @@ -448,34 +448,35 @@ ia32_sys_call_table: .quad compat_sys_sched_getaffinity .quad sys32_set_thread_area .quad sys32_get_thread_area - .quad sys32_io_setup + .quad sys32_io_setup /* 245 */ .quad sys_io_destroy .quad sys32_io_getevents .quad sys32_io_submit .quad sys_io_cancel - .quad sys_fadvise64 + .quad sys_fadvise64 /* 250 */ .quad sys_ni_syscall /* free_huge_pages */ .quad sys_exit_group /* exit_group */ .quad sys_lookup_dcookie .quad sys_epoll_create - .quad sys_epoll_ctl + .quad sys_epoll_ctl /* 255 */ .quad sys_epoll_wait .quad sys_remap_file_pages .quad sys_set_tid_address .quad sys32_timer_create - .quad compat_timer_settime + .quad compat_timer_settime /* 260 */ .quad compat_timer_gettime .quad sys_timer_getoverrun .quad sys_timer_delete .quad compat_clock_settime - .quad compat_clock_gettime + .quad compat_clock_gettime /* 265 */ .quad compat_clock_getres .quad compat_clock_nanosleep .quad compat_statfs64 /* statfs64 */ .quad compat_fstatfs64 /* fstatfs64 */ - .quad sys_tgkill + .quad sys_tgkill /* 270 */ .quad compat_sys_utimes .quad sys32_fadvise64_64 + .quad sys_vserver /* 273 sys_vserver */ /* don't forget to change IA32_NR_syscalls */ ia32_syscall_end: .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8 diff -NurpP --minimal linux-2.6.0-test11/fs/inode.c linux-2.6.0-test11-vs0.02/fs/inode.c --- linux-2.6.0-test11/fs/inode.c Wed Nov 26 21:45:53 2003 +++ linux-2.6.0-test11-vs0.02/fs/inode.c Fri Dec 12 18:22:36 2003 @@ -131,6 +131,7 @@ static struct inode *alloc_inode(struct inode->i_bdev = NULL; inode->i_cdev = NULL; inode->i_rdev = 0; + inode->i_xid = 0; /* maybe not too wise ... */ inode->i_security = NULL; if (security_inode_alloc(inode)) { if (inode->i_sb->s_op->destroy_inode) diff -NurpP --minimal linux-2.6.0-test11/fs/proc/Makefile linux-2.6.0-test11-vs0.02/fs/proc/Makefile --- linux-2.6.0-test11/fs/proc/Makefile Wed Nov 26 21:42:56 2003 +++ linux-2.6.0-test11-vs0.02/fs/proc/Makefile Fri Dec 12 18:22:36 2003 @@ -8,7 +8,7 @@ proc-y := task_nommu.o proc-$(CONFIG_MMU) := task_mmu.o proc-y += inode.o root.o base.o generic.o array.o \ - kmsg.o proc_tty.o proc_misc.o + kmsg.o proc_tty.o proc_misc.o virtual.o proc-$(CONFIG_PROC_KCORE) += kcore.o proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o diff -NurpP --minimal linux-2.6.0-test11/fs/proc/base.c linux-2.6.0-test11-vs0.02/fs/proc/base.c --- linux-2.6.0-test11/fs/proc/base.c Wed Nov 26 21:44:31 2003 +++ linux-2.6.0-test11-vs0.02/fs/proc/base.c Fri Dec 12 23:22:55 2003 @@ -32,6 +32,7 @@ #include #include #include +#include /* * For hysterical raisins we keep the same inumbers as in the old procfs. @@ -67,6 +68,7 @@ enum pid_directory_inos { PROC_TGID_ATTR_EXEC, PROC_TGID_ATTR_FSCREATE, #endif + PROC_TGID_VINFO, PROC_TGID_FD_DIR, PROC_TID_INO, PROC_TID_STATUS, @@ -90,6 +92,7 @@ enum pid_directory_inos { PROC_TID_ATTR_EXEC, PROC_TID_ATTR_FSCREATE, #endif + PROC_TID_VINFO, PROC_TID_FD_DIR = 0x8000, /* 0x8000-0xffff */ }; @@ -123,6 +126,7 @@ static struct pid_entry tgid_base_stuff[ #ifdef CONFIG_KALLSYMS E(PROC_TGID_WCHAN, "wchan", S_IFREG|S_IRUGO), #endif + E(PROC_TGID_VINFO, "vinfo", S_IFREG|S_IRUGO), {0,0,NULL,0} }; static struct pid_entry tid_base_stuff[] = { @@ -145,6 +149,7 @@ static struct pid_entry tid_base_stuff[] #ifdef CONFIG_KALLSYMS E(PROC_TID_WCHAN, "wchan", S_IFREG|S_IRUGO), #endif + E(PROC_TID_VINFO, "vinfo", S_IFREG|S_IRUGO), {0,0,NULL,0} }; @@ -181,6 +186,7 @@ int proc_pid_stat(struct task_struct*,ch int proc_pid_status(struct task_struct*,char*); int proc_pid_statm(struct task_struct*,char*); int proc_pid_cpu(struct task_struct*,char*); +int proc_pid_vinfo(struct task_struct*,char*); static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt) { @@ -932,6 +938,7 @@ static struct inode *proc_pid_make_inode inode->i_uid = task->euid; inode->i_gid = task->egid; } + inode->i_xid = vx_task_id(task); security_task_to_inode(task, inode); out: @@ -1361,6 +1368,11 @@ static struct dentry *proc_pident_lookup ei->op.proc_read = proc_pid_wchan; break; #endif + case PROC_TID_VINFO: + case PROC_TGID_VINFO: + inode->i_fop = &proc_info_file_operations; + ei->op.proc_read = proc_pid_vinfo; + break; default: printk("procfs: impossible type (%d)",p->type); iput(inode); @@ -1552,6 +1564,10 @@ struct dentry *proc_pid_lookup(struct in if (!task) goto out; + if (tgid != 1 && !vx_check(task->vx_info, VX_WATCH|VX_IDENT)) { + put_task_struct(task); + goto out; + } inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO); @@ -1599,7 +1615,6 @@ static struct dentry *proc_task_lookup(s inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO); - if (!inode) { put_task_struct(task); goto out; @@ -1641,6 +1656,10 @@ static int get_tgid_list(int index, unsi for_each_process(p) { int tgid = p->pid; if (!pid_alive(p)) + continue; + if (tgid != 1 && !vx_check(p->vx_info, VX_WATCH|VX_IDENT)) + continue; + if (current->vx_info && current->vx_info->vx_initpid == tgid) continue; if (--index >= 0) continue; diff -NurpP --minimal linux-2.6.0-test11/fs/proc/generic.c linux-2.6.0-test11-vs0.02/fs/proc/generic.c --- linux-2.6.0-test11/fs/proc/generic.c Wed Nov 26 21:46:04 2003 +++ linux-2.6.0-test11-vs0.02/fs/proc/generic.c Sat Dec 13 00:06:11 2003 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -424,9 +425,12 @@ int proc_readdir(struct file * filp, } do { + if (de->vx_flags && !vx_check_id(de->xid, de->vx_flags)) + goto skip; if (filldir(dirent, de->name, de->namelen, filp->f_pos, de->low_ino, de->mode >> 12) < 0) goto out; + skip: filp->f_pos++; de = de->next; } while (de); diff -NurpP --minimal linux-2.6.0-test11/fs/proc/inode.c linux-2.6.0-test11-vs0.02/fs/proc/inode.c --- linux-2.6.0-test11/fs/proc/inode.c Wed Nov 26 21:45:31 2003 +++ linux-2.6.0-test11-vs0.02/fs/proc/inode.c Sat Dec 13 00:04:31 2003 @@ -207,6 +207,9 @@ printk("proc_iget: using deleted entry % inode->i_uid = de->uid; inode->i_gid = de->gid; } + inode->i_xid = de->xid; + if (de->vx_flags) + PROC_I(inode)->vx_flags = de->vx_flags; if (de->size) inode->i_size = de->size; if (de->nlink) diff -NurpP --minimal linux-2.6.0-test11/fs/proc/root.c linux-2.6.0-test11-vs0.02/fs/proc/root.c --- linux-2.6.0-test11/fs/proc/root.c Wed Nov 26 21:45:08 2003 +++ linux-2.6.0-test11-vs0.02/fs/proc/root.c Fri Dec 12 18:22:36 2003 @@ -23,6 +23,7 @@ struct proc_dir_entry *proc_net, *proc_b #ifdef CONFIG_SYSCTL struct proc_dir_entry *proc_sys_root; #endif +struct proc_dir_entry *proc_virtual; static struct super_block *proc_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) @@ -78,6 +79,7 @@ void __init proc_root_init(void) proc_rtas_init(); #endif proc_bus = proc_mkdir("bus", 0); + proc_virtual = proc_mkdir("virtual", 0); } static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd) diff -NurpP --minimal linux-2.6.0-test11/fs/proc/virtual.c linux-2.6.0-test11-vs0.02/fs/proc/virtual.c --- linux-2.6.0-test11/fs/proc/virtual.c Thu Jan 1 01:00:00 1970 +++ linux-2.6.0-test11-vs0.02/fs/proc/virtual.c Fri Dec 12 22:41:19 2003 @@ -0,0 +1,181 @@ +/* + * linux/fs/proc/virtual.c + * + * Virtual Context ProcFS Support + * + * Copyright (C) 2003 Herbert Pötzl + * + * V0.01 basic directory array + * V0.02 per context info & stat + * V0.03 proc permissions + * + */ + +#include + +#include +#include +#include + +#include +#include + +#include +#include + + +extern struct proc_dir_entry *proc_virtual; +static struct proc_dir_entry *proc_virtual_info; + + +char *task_vinfo(struct task_struct *p, char *buffer) +{ + return buffer + sprintf(buffer, + "VxID:\t%d\n" + ,__vx_id(p->vx_info)); +} + +int proc_pid_vinfo(struct task_struct *p, char *buffer) +{ + char * orig = buffer; + + buffer = task_vinfo(p, buffer); + return buffer - orig; +} + + +static int __generic_info_read_func(char *page, char **start, + off_t off, int count, int *eof, void *data, + char *(*info_func)(void *, char *)) +{ + int len; + char *buffer = page; + + buffer = info_func(data, buffer); + + len = buffer-page; + if (len <= off+count) *eof = 1; + + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + +char *vx_proc_info (void *data, char *buffer) +{ + struct vx_info *vxi = data; + buffer += sprintf(buffer, + "VxID:\t%d\n" + "Info:\t%p\n" + "Init:\t%d\n" + ,__vx_id(vxi) + ,vxi + ,vxi->vx_initpid); + return buffer; +} + +int vx_info_read_func (char *page, char **start, + off_t off, int count, int *eof, void *data) +{ + return __generic_info_read_func(page, start, + off, count, eof, data, vx_proc_info); +} + +char *vx_proc_status (void *data, char *buffer) +{ + struct vx_info *vxi = data; + buffer += sprintf(buffer, + "RefC:\t%d\n" + "Flags:\t%08x\n" + "Ticks:\t%d\n" + ,atomic_read(&vxi->vx_refcount) + ,vxi->vx_flags + ,atomic_read(&vxi->limit.ticks)); + return buffer; +} + +int vx_status_read_func (char *page, char **start, + off_t off, int count, int *eof, void *data) +{ + return __generic_info_read_func(page, start, + off, count, eof, data, vx_proc_status); +} + + +static int vx_proc_permission(struct inode *inode, + int mask, struct nameidata *nd) +{ + dprintk("vx_proc_permission(%p) = #%d,%04x\n", + inode, inode->i_xid, PROC_I(inode)->vx_flags); + if (vx_check_id(inode->i_xid, PROC_I(inode)->vx_flags)) + return 0; + dprintk("vx_proc_permission(%p) #%d != #%d\n", + inode, inode->i_xid, vx_current_id()); + return -ENOENT; +} + +static struct inode_operations vx_proc_inode_operations = { + .lookup = proc_lookup, + .permission = vx_proc_permission, +}; + + +int vx_proc_create(struct vx_info *vxi) +{ + struct proc_dir_entry *entry, *sub; + char name[8]; + + snprintf(name, sizeof(name)-1, "%d", __vx_id(vxi)); + entry = create_proc_entry(name, + S_IFDIR|S_IXUGO, proc_virtual); + entry->vx_flags = VX_ADMIN|VX_WATCH|VX_SAME; + entry->xid = __vx_id(vxi); + entry->proc_iops = &vx_proc_inode_operations; + vxi->vx_procent = entry; + sub = create_proc_read_entry("info", + S_IFREG|S_IRUGO|S_IWUSR, + entry, vx_info_read_func, vxi); + sub = create_proc_read_entry("status", + S_IFREG|S_IRUGO|S_IWUSR, + entry, vx_status_read_func, vxi); + return 0; +} + +int vx_proc_destroy(struct vx_info *vxi) +{ + struct proc_dir_entry *entry = vxi->vx_procent; + if (!entry) + return 0; + remove_proc_entry(entry->name, proc_virtual); + vxi->vx_procent = NULL; + return 0; +} + +char *vs_proc_info(void *data, char *buffer) +{ + buffer += sprintf(buffer, + "VCIVersion:\t%04x:%04x\n" + ,VCI_VERSION >> 16 + ,VCI_VERSION & 0xFFFF); + return buffer; +} + +int vs_info_read_func(char *page, char **start, + off_t off, int count, int *eof, void *data) +{ + return __generic_info_read_func(page, start, + off, count, eof, data, vs_proc_info); +} + + +static int __init virtual_proc_init(void) +{ + proc_virtual_info = create_proc_read_entry("info", + S_IFREG|S_IRUGO|S_IWUSR, + proc_virtual, vs_info_read_func, NULL); + return 0; +} + +__initcall(virtual_proc_init); diff -NurpP --minimal linux-2.6.0-test11/include/asm-alpha/unistd.h linux-2.6.0-test11-vs0.02/include/asm-alpha/unistd.h --- linux-2.6.0-test11/include/asm-alpha/unistd.h Wed Nov 26 21:43:40 2003 +++ linux-2.6.0-test11-vs0.02/include/asm-alpha/unistd.h Fri Dec 12 18:22:36 2003 @@ -233,6 +233,7 @@ #define __NR_osf_memcntl 260 /* not implemented */ #define __NR_osf_fdatasync 261 /* not implemented */ +#define __NR_vserver 273 /* * Linux-specific system calls begin at 300 diff -NurpP --minimal linux-2.6.0-test11/include/asm-m68k/unistd.h linux-2.6.0-test11-vs0.02/include/asm-m68k/unistd.h --- linux-2.6.0-test11/include/asm-m68k/unistd.h Wed Nov 26 21:44:06 2003 +++ linux-2.6.0-test11-vs0.02/include/asm-m68k/unistd.h Fri Dec 12 16:48:36 2003 @@ -239,7 +239,9 @@ #define __NR_fremovexattr 234 #define __NR_futex 235 -#define NR_syscalls 236 +#define __NR_vserver 273 + +#define NR_syscalls 274 /* user-visible error numbers are in the range -1 - -124: see */ diff -NurpP --minimal linux-2.6.0-test11/include/asm-m68knommu/unistd.h linux-2.6.0-test11-vs0.02/include/asm-m68knommu/unistd.h --- linux-2.6.0-test11/include/asm-m68knommu/unistd.h Wed Nov 26 21:44:12 2003 +++ linux-2.6.0-test11-vs0.02/include/asm-m68knommu/unistd.h Fri Dec 12 16:49:18 2003 @@ -221,7 +221,9 @@ #define __NR_setfsuid32 215 #define __NR_setfsgid32 216 -#define NR_syscalls 256 +#define __NR_vserver 273 + +#define NR_syscalls 274 /* user-visible error numbers are in the range -1 - -122: see */ diff -NurpP --minimal linux-2.6.0-test11/include/asm-mips/unistd.h linux-2.6.0-test11-vs0.02/include/asm-mips/unistd.h --- linux-2.6.0-test11/include/asm-mips/unistd.h Wed Nov 26 21:42:50 2003 +++ linux-2.6.0-test11-vs0.02/include/asm-mips/unistd.h Fri Dec 12 16:51:56 2003 @@ -289,10 +289,12 @@ #define __NR_tgkill (__NR_Linux + 266) #define __NR_utimes (__NR_Linux + 267) +#define __NR_vserver (__NR_Linux + 273) + /* * Offset of the last Linux o32 flavoured syscall */ -#define __NR_Linux_syscalls 267 +#define __NR_Linux_syscalls 273 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ diff -NurpP --minimal linux-2.6.0-test11/include/asm-parisc/unistd.h linux-2.6.0-test11-vs0.02/include/asm-parisc/unistd.h --- linux-2.6.0-test11/include/asm-parisc/unistd.h Wed Nov 26 21:42:47 2003 +++ linux-2.6.0-test11-vs0.02/include/asm-parisc/unistd.h Fri Dec 12 16:52:49 2003 @@ -722,8 +722,9 @@ #define __NR_remap_file_pages (__NR_Linux + 227) #define __NR_semtimedop (__NR_Linux + 228) +#define __NR_vserver (__NR_Linux + 273) -#define __NR_Linux_syscalls 228 +#define __NR_Linux_syscalls 273 #define HPUX_GATEWAY_ADDR 0xC0000004 #define LINUX_GATEWAY_ADDR 0x100 diff -NurpP --minimal linux-2.6.0-test11/include/asm-ppc/unistd.h linux-2.6.0-test11-vs0.02/include/asm-ppc/unistd.h --- linux-2.6.0-test11/include/asm-ppc/unistd.h Wed Nov 26 21:43:24 2003 +++ linux-2.6.0-test11-vs0.02/include/asm-ppc/unistd.h Fri Dec 12 16:53:29 2003 @@ -260,7 +260,9 @@ #define __NR_fstatfs64 253 #define __NR_fadvise64_64 254 -#define __NR_syscalls 255 +#define __NR_vserver 273 + +#define __NR_syscalls 274 #define __NR(n) #n diff -NurpP --minimal linux-2.6.0-test11/include/asm-ppc64/unistd.h linux-2.6.0-test11-vs0.02/include/asm-ppc64/unistd.h --- linux-2.6.0-test11/include/asm-ppc64/unistd.h Wed Nov 26 21:42:50 2003 +++ linux-2.6.0-test11-vs0.02/include/asm-ppc64/unistd.h Fri Dec 12 16:54:00 2003 @@ -265,7 +265,9 @@ #define __NR_statfs64 252 #define __NR_fstatfs64 253 -#define __NR_syscalls 254 +#define __NR_vserver 273 + +#define __NR_syscalls 274 #ifdef __KERNEL__ #define NR_syscalls __NR_syscalls #endif diff -NurpP --minimal linux-2.6.0-test11/include/asm-s390/unistd.h linux-2.6.0-test11-vs0.02/include/asm-s390/unistd.h --- linux-2.6.0-test11/include/asm-s390/unistd.h Wed Nov 26 21:46:11 2003 +++ linux-2.6.0-test11-vs0.02/include/asm-s390/unistd.h Fri Dec 12 16:54:54 2003 @@ -256,9 +256,7 @@ #define __NR_clock_gettime (__NR_timer_create+6) #define __NR_clock_getres (__NR_timer_create+7) #define __NR_clock_nanosleep (__NR_timer_create+8) -/* - * Number 263 is reserved for vserver - */ +#define __NR_vserver 263 #define NR_syscalls 264 diff -NurpP --minimal linux-2.6.0-test11/include/asm-sh/unistd.h linux-2.6.0-test11-vs0.02/include/asm-sh/unistd.h --- linux-2.6.0-test11/include/asm-sh/unistd.h Wed Nov 26 21:45:27 2003 +++ linux-2.6.0-test11-vs0.02/include/asm-sh/unistd.h Fri Dec 12 16:57:30 2003 @@ -276,7 +276,9 @@ #define __NR_clock_getres (__NR_timer_create+7) #define __NR_clock_nanosleep (__NR_timer_create+8) -#define NR_syscalls 268 +#define __NR_vserver 273 + +#define NR_syscalls 274 /* user-visible error numbers are in the range -1 - -124: see */ diff -NurpP --minimal linux-2.6.0-test11/include/asm-sparc/unistd.h linux-2.6.0-test11-vs0.02/include/asm-sparc/unistd.h --- linux-2.6.0-test11/include/asm-sparc/unistd.h Wed Nov 26 21:42:56 2003 +++ linux-2.6.0-test11-vs0.02/include/asm-sparc/unistd.h Fri Dec 12 17:56:20 2003 @@ -283,7 +283,7 @@ #define __NR_timer_getoverrun 264 #define __NR_timer_delete 265 #define __NR_timer_create 266 -/* #define __NR_vserver 267 Reserved for VSERVER */ +#define __NR_vserver 267 #define __NR_io_setup 268 #define __NR_io_destroy 268 #define __NR_io_submit 269 diff -NurpP --minimal linux-2.6.0-test11/include/asm-sparc64/unistd.h linux-2.6.0-test11-vs0.02/include/asm-sparc64/unistd.h --- linux-2.6.0-test11/include/asm-sparc64/unistd.h Wed Nov 26 21:43:09 2003 +++ linux-2.6.0-test11-vs0.02/include/asm-sparc64/unistd.h Fri Dec 12 17:56:46 2003 @@ -285,7 +285,7 @@ #define __NR_timer_getoverrun 264 #define __NR_timer_delete 265 #define __NR_timer_create 266 -/* #define __NR_vserver 267 Reserved for VSERVER */ +#define __NR_vserver 267 #define __NR_io_setup 268 #define __NR_io_destroy 268 #define __NR_io_submit 269 diff -NurpP --minimal linux-2.6.0-test11/include/asm-x86_64/ia32_unistd.h linux-2.6.0-test11-vs0.02/include/asm-x86_64/ia32_unistd.h --- linux-2.6.0-test11/include/asm-x86_64/ia32_unistd.h Wed Nov 26 21:44:33 2003 +++ linux-2.6.0-test11-vs0.02/include/asm-x86_64/ia32_unistd.h Fri Dec 12 18:22:36 2003 @@ -278,6 +278,7 @@ #define __NR_ia32_tgkill 270 #define __NR_ia32_utimes 271 #define __NR_ia32_fadvise64_64 272 +#define __NR_ia32_vserver 273 #define IA32_NR_syscalls 275 /* must be > than biggest syscall! */ diff -NurpP --minimal linux-2.6.0-test11/include/linux/fs.h linux-2.6.0-test11-vs0.02/include/linux/fs.h --- linux-2.6.0-test11/include/linux/fs.h Wed Nov 26 21:43:26 2003 +++ linux-2.6.0-test11-vs0.02/include/linux/fs.h Fri Dec 12 22:20:26 2003 @@ -376,6 +376,7 @@ struct inode { unsigned int i_nlink; uid_t i_uid; gid_t i_gid; + xid_t i_xid; dev_t i_rdev; loff_t i_size; struct timespec i_atime; diff -NurpP --minimal linux-2.6.0-test11/include/linux/proc_fs.h linux-2.6.0-test11-vs0.02/include/linux/proc_fs.h --- linux-2.6.0-test11/include/linux/proc_fs.h Wed Nov 26 21:42:41 2003 +++ linux-2.6.0-test11-vs0.02/include/linux/proc_fs.h Fri Dec 12 21:00:49 2003 @@ -60,6 +60,8 @@ struct proc_dir_entry { nlink_t nlink; uid_t uid; gid_t gid; + xid_t xid; + int vx_flags; unsigned long size; struct inode_operations * proc_iops; struct file_operations * proc_fops; @@ -236,6 +238,7 @@ extern struct kcore_list *kclist_del(voi struct proc_inode { struct task_struct *task; int type; + int vx_flags; union { int (*proc_get_link)(struct inode *, struct dentry **, struct vfsmount **); int (*proc_read)(struct task_struct *task, char *page); diff -NurpP --minimal linux-2.6.0-test11/include/linux/sched.h linux-2.6.0-test11-vs0.02/include/linux/sched.h --- linux-2.6.0-test11/include/linux/sched.h Wed Nov 26 21:42:58 2003 +++ linux-2.6.0-test11-vs0.02/include/linux/sched.h Sat Dec 13 00:40:47 2003 @@ -297,9 +297,10 @@ struct user_struct { /* Hash table maintenance information */ struct list_head uidhash_list; uid_t uid; + int vx_id; }; -extern struct user_struct *find_user(uid_t); +extern struct user_struct *find_user(xid_t, uid_t); extern struct user_struct root_user; #define INIT_USER (&root_user) @@ -441,6 +442,10 @@ struct task_struct { void *security; + kernel_cap_t cap_bset; + struct vx_info *vx_info; + // struct iproot_info *ip_info; + /* Thread group tracking */ u32 parent_exec_id; u32 self_exec_id; @@ -562,7 +567,7 @@ extern void set_special_pids(pid_t sessi extern void __set_special_pids(pid_t session, pid_t pgrp); /* per-UID process charging. */ -extern struct user_struct * alloc_uid(uid_t); +extern struct user_struct * alloc_uid(xid_t, uid_t); extern void free_uid(struct user_struct *); extern void switch_uid(struct user_struct *); diff -NurpP --minimal linux-2.6.0-test11/include/linux/types.h linux-2.6.0-test11-vs0.02/include/linux/types.h --- linux-2.6.0-test11/include/linux/types.h Wed Nov 26 21:45:29 2003 +++ linux-2.6.0-test11-vs0.02/include/linux/types.h Fri Dec 12 22:16:04 2003 @@ -37,6 +37,7 @@ typedef __kernel_uid32_t uid_t; typedef __kernel_gid32_t gid_t; typedef __kernel_uid16_t uid16_t; typedef __kernel_gid16_t gid16_t; +typedef unsigned int xid_t; #ifdef CONFIG_UID16 /* This is defined by include/asm-{arch}/posix_types.h */ diff -NurpP --minimal linux-2.6.0-test11/include/linux/vcontext.h linux-2.6.0-test11-vs0.02/include/linux/vcontext.h --- linux-2.6.0-test11/include/linux/vcontext.h Thu Jan 1 01:00:00 1970 +++ linux-2.6.0-test11-vs0.02/include/linux/vcontext.h Fri Dec 12 23:05:19 2003 @@ -0,0 +1,164 @@ +#ifndef _VX_CONTEXT_H +#define _VX_CONTEXT_H + +#define DEBUG_VX +#if defined(DEBUG) || defined(DEBUG_VX) +#include +#define dprintk(x...) printk("vxd: " x) +#else +#define dprintk(x...) +#endif + + +#define VX_INFO_LOCK 1 /* Can't request a new vx_id */ +#define VX_INFO_SCHED 2 /* All process in the vx_id */ + /* Contribute to the schedular */ +#define VX_INFO_NPROC 4 /* Limit number of processes in a context */ +#define VX_INFO_PRIVATE 8 /* Noone can join this security context */ +#define VX_INFO_INIT 16 /* This process wants to become the */ + /* logical process 1 of the security */ + /* context */ +#define VX_INFO_HIDEINFO 32 /* Hide some information in /proc */ +#define VX_INFO_ULIMIT 64 /* Use ulimit of the current process */ + /* to become the global limits */ + /* of the context */ + +#define MAX_S_CONTEXT 65535 /* Arbitrary limit */ +#define MIN_D_CONTEXT 49152 /* dynamic contexts start here */ + +#define NB_S_CONTEXT 16 + +#define NB_IPV4ROOT 16 + +#include +#include +#include +#include +#include + + +extern struct list_head vx_infos; +extern spinlock_t vxlist_lock; + + +struct _vx_virt { + int nr_threads; + int nr_running; + int max_threads; + unsigned long total_forks; + + unsigned int bias_cswtch; + long bias_jiffies; + long bias_idle; + + struct new_utsname utsname; +}; + +struct _vx_limit { + atomic_t ticks; + + unsigned long rlim[RLIM_NLIMITS]; /* Per context limit */ + atomic_t res[RLIM_NLIMITS]; /* Current value */ +}; + +struct vx_info { + struct list_head vx_list; /* linked list of contexts */ + xid_t vx_id; /* context id */ + atomic_t vx_refcount; /* refcount */ + struct vx_info *vx_parent; /* parent context */ + + struct proc_dir_entry *vx_procent; /* proc entry */ + unsigned int vx_flags; /* VX_INFO_xxx */ + pid_t vx_initpid; /* PID of fake init process */ + + struct _vx_virt virt; /* virtual/bias stuff */ + struct _vx_limit limit; /* vserver limits */ +}; + +struct vx_net { + atomic_t refcount; +}; + + +void free_vx_info(struct vx_info *); +extern int proc_pid_vinfo(struct task_struct *, char *); + +static inline struct vx_info *get_vx_info(struct vx_info *vxi) +{ + dprintk("get_vx_info(%p[#%d.%d])\n", vxi, + vxi->vx_id, atomic_read(&vxi->vx_refcount)); + atomic_inc(&vxi->vx_refcount); + return vxi; +} + +static inline void put_vx_info(struct vx_info *vxi) +{ + /* for now we allow vxi to be null */ + if (!vxi) + return; + dprintk("put_vx_info(%p[#%d.%d])\n", vxi, + vxi->vx_id, atomic_read(&vxi->vx_refcount)); + if (atomic_dec_and_lock(&vxi->vx_refcount, &vxlist_lock)) { + list_del(&vxi->vx_list); + spin_unlock(&vxlist_lock); + free_vx_info(vxi); + } +} + + +#define VX_ADMIN 0x0001 +#define VX_WATCH 0x0002 + +#define VX_IDENT 0x0010 /* pointer based */ +#define VX_SAME 0x0020 /* id based */ +#define VX_PARENT 0x0040 +#define VX_CHILD 0x0080 + +#define VX_ARG_MASK 0x00F0 + +#include + +/* required to resolve recursive dependancies */ +#define vx_task_id(t) __vx_id(t->vx_info) + +#define vx_current_id() vx_task_id(current) + +static inline int __vx_id(struct vx_info *vxi) +{ + if (!vxi) + return 0; + return vxi->vx_id; +} + +/* required to resolve recursive dependancies */ +#define vx_check(c,m) \ + __vx_check(current->vx_info,c,__vx_id(c),m) + +#define vx_check_id(c,m) \ + __vx_check(current->vx_info,0,c,m) + +/* + * check current context for ADMIN/WATCH and + * optionally agains supplied argument + */ +static inline int __vx_check(struct vx_info *cvxi, + struct vx_info *vxi, int id, unsigned int mode) +{ + if (mode & VX_ARG_MASK) { + if ((mode & VX_IDENT) && + (vxi == cvxi)) + return 1; + if ((mode & VX_SAME) && + (__vx_id(cvxi) == id)) + return 1; + } + return (((mode & VX_ADMIN) && (cvxi == 0)) || + ((mode & VX_WATCH) && (cvxi) && + (__vx_id(cvxi) == 1))); +} + + +int vc_new_s_context(uint32_t, void *); +int vc_set_ipv4root(uint32_t, void *); + +#endif diff -NurpP --minimal linux-2.6.0-test11/include/linux/vswitch.h linux-2.6.0-test11-vs0.02/include/linux/vswitch.h --- linux-2.6.0-test11/include/linux/vswitch.h Thu Jan 1 01:00:00 1970 +++ linux-2.6.0-test11-vs0.02/include/linux/vswitch.h Fri Dec 12 20:11:16 2003 @@ -0,0 +1,122 @@ +#ifndef _LINUX_VIRTUAL_H +#define _LINUX_VIRTUAL_H + +#include +#include + +#define VC_CATEGORY(c) (((c) >> 24) & 0x3F) +#define VC_COMMAND(c) (((c) >> 16) & 0xFF) +#define VC_VERSION(c) ((c) & 0xFFF) + +#define VC_CMD(c,i,v) ((((VC_CAT_ ## c) & 0x3F) << 24) \ + | (((i) & 0xFF) << 16) | ((v) & 0xFFF)) + +/* + + Syscall Matrix V2.3 + + |VERSION|CREATE |MODIFY |MIGRATE|CONTROL|EXPERIM| |SPECIAL|SPECIAL| + |STATS |DESTROY|ALTER |CHANGE |LIMIT |TEST | | | | + |INFO |SETUP | |MOVE | | | | | | + -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ + SYSTEM |VERSION| | | | | | |DEVICES| | + HOST | 00| 01| 02| 03| 04| 05| | 06| 07| + -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ + CPU | | | | | | | |SCHED. | | + PROCESS| 08| 09| 10| 11| 12| 13| | 14| 15| + -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ + MEMORY | | | | | | | |SWAP | | + | 16| 17| 18| 19| 20| 21| | 22| 23| + -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ + NETWORK| | | | | | | |SERIAL | | + | 24| 25| 26| 27| 28| 29| | 30| 31| + -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ + DISK | | | | | | | | | | + VFS | 32| 33| 34| 35| 36| 37| | 38| 39| + -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ + OTHER | | | | | | | | | | + | 40| 41| 42| 43| 44| 45| | 46| 47| + =======+=======+=======+=======+=======+=======+=======+ +=======+=======+ + SPECIAL| | | | | | | | | | + | 48| 49| 50| 51| 52| 53| | 54| 55| + -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ + SPECIAL| | | | |RLIMIT |SYSCALL| | |COMPAT | + | 56| 57| 58| 59| 60|TEST 61| | 62| 63| + -------+-------+-------+-------+-------+-------+-------+ +-------+-------+ + +*/ + +#define VC_CAT_VERSION 0 + +#define VC_CAT_PROCTRL 12 + +#define VC_CAT_RLIMIT 60 + +#define VC_CAT_SYSTEST 61 +#define VC_CAT_COMPAT 63 + +/* interface version */ + +#define VCI_VERSION 0x00010004 + + + +/* query version */ + +#define VCMD_get_version VC_CMD(VERSION, 0, 0) + + +/* compatibiliy vserver commands */ + +#define VCMD_new_s_context VC_CMD(COMPAT, 1, 1) +#define VCMD_set_ipv4root VC_CMD(COMPAT, 2, 3) + +/* compatibiliy vserver arguments */ + +struct vcmd_new_s_context_v1 { + uint32_t remove_cap; + uint32_t flags; +}; + +struct vcmd_set_ipv4root_v3 { + /* number of pairs in id */ + uint32_t broadcast; + struct { + uint32_t ip; + uint32_t mask; + } ip_mask_pair[NB_IPV4ROOT]; +}; + +/* context signalling */ + +#define VCMD_ctx_kill VC_CMD(PROCTRL, 1, 0) + +struct vcmd_ctx_kill_v0 { + int32_t pid; + int32_t sig; +}; + +/* rlimit vserver commands */ + +#define VCMD_get_rlimit VC_CMD(RLIMIT, 1, 0) +#define VCMD_set_rlimit VC_CMD(RLIMIT, 2, 0) +#define VCMD_get_rlimit_mask VC_CMD(RLIMIT, 3, 0) + +struct vcmd_ctx_rlimit_v0 { + uint32_t id; + uint64_t minimum; + uint64_t softlimit; + uint64_t maximum; +}; + +struct vcmd_ctx_rlimit_mask_v0 { + uint32_t minimum; + uint32_t softlimit; + uint32_t maximum; +}; + +#define CRLIM_INFINITY (~0ULL) +#define CRLIM_KEEP (~1ULL) + + +#endif /* _LINUX_VIRTUAL_H */ diff -NurpP --minimal linux-2.6.0-test11/kernel/Makefile linux-2.6.0-test11-vs0.02/kernel/Makefile --- linux-2.6.0-test11/kernel/Makefile Wed Nov 26 21:43:24 2003 +++ linux-2.6.0-test11-vs0.02/kernel/Makefile Fri Dec 12 18:22:36 2003 @@ -3,9 +3,9 @@ # obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \ - exit.o itimer.o time.o softirq.o resource.o \ + exit.o itimer.o time.o softirq.o resource.o vswitch.o \ sysctl.o capability.o ptrace.o timer.o user.o \ - signal.o sys.o kmod.o workqueue.o pid.o \ + signal.o sys.o kmod.o workqueue.o pid.o vcontext.o \ rcupdate.o intermodule.o extable.o params.o posix-timers.o obj-$(CONFIG_FUTEX) += futex.o diff -NurpP --minimal linux-2.6.0-test11/kernel/fork.c linux-2.6.0-test11-vs0.02/kernel/fork.c --- linux-2.6.0-test11/kernel/fork.c Wed Nov 26 21:42:58 2003 +++ linux-2.6.0-test11-vs0.02/kernel/fork.c Sat Dec 13 01:09:59 2003 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -76,6 +77,7 @@ static kmem_cache_t *task_struct_cachep; static void free_task(struct task_struct *tsk) { free_thread_info(tsk->thread_info); + put_vx_info(tsk->vx_info); free_task_struct(tsk); } @@ -832,6 +834,11 @@ struct task_struct *copy_process(unsigne p->user != &root_user) goto bad_fork_free; } + + if (current->vx_info) + p->vx_info = get_vx_info(current->vx_info); + else + p->vx_info = NULL; atomic_inc(&p->user->__count); atomic_inc(&p->user->processes); diff -NurpP --minimal linux-2.6.0-test11/kernel/sys.c linux-2.6.0-test11-vs0.02/kernel/sys.c --- linux-2.6.0-test11/kernel/sys.c Wed Nov 26 21:42:58 2003 +++ linux-2.6.0-test11-vs0.02/kernel/sys.c Fri Dec 12 18:22:36 2003 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -314,7 +315,7 @@ asmlinkage long sys_setpriority(int whic if (!who) user = current->user; else - user = find_user(who); + user = find_user(vx_current_id(), who); if (!user) goto out_unlock; @@ -373,7 +374,7 @@ asmlinkage long sys_getpriority(int whic if (!who) user = current->user; else - user = find_user(who); + user = find_user(vx_current_id(), who); if (!user) goto out_unlock; @@ -614,7 +615,7 @@ static int set_user(uid_t new_ruid, int { struct user_struct *new_user; - new_user = alloc_uid(new_ruid); + new_user = alloc_uid(vx_current_id(), new_ruid); if (!new_user) return -EAGAIN; diff -NurpP --minimal linux-2.6.0-test11/kernel/user.c linux-2.6.0-test11-vs0.02/kernel/user.c --- linux-2.6.0-test11/kernel/user.c Wed Nov 26 21:43:35 2003 +++ linux-2.6.0-test11-vs0.02/kernel/user.c Fri Dec 12 18:22:36 2003 @@ -20,8 +20,8 @@ #define UIDHASH_BITS 8 #define UIDHASH_SZ (1 << UIDHASH_BITS) #define UIDHASH_MASK (UIDHASH_SZ - 1) -#define __uidhashfn(uid) (((uid >> UIDHASH_BITS) + uid) & UIDHASH_MASK) -#define uidhashentry(uid) (uidhash_table + __uidhashfn((uid))) +#define __uidhashfn(xid,uid) ((((uid) >> UIDHASH_BITS) + ((uid)^(xid))) & UIDHASH_MASK) +#define uidhashentry(xid,uid) (uidhash_table + __uidhashfn((xid),(uid))) static kmem_cache_t *uid_cachep; static struct list_head uidhash_table[UIDHASH_SZ]; @@ -46,7 +46,7 @@ static inline void uid_hash_remove(struc list_del(&up->uidhash_list); } -static inline struct user_struct *uid_hash_find(uid_t uid, struct list_head *hashent) +static inline struct user_struct *uid_hash_find(xid_t xid, uid_t uid, struct list_head *hashent) { struct list_head *up; @@ -55,7 +55,7 @@ static inline struct user_struct *uid_ha user = list_entry(up, struct user_struct, uidhash_list); - if(user->uid == uid) { + if(user->uid == uid && user->vx_id == xid) { atomic_inc(&user->__count); return user; } @@ -64,9 +64,9 @@ static inline struct user_struct *uid_ha return NULL; } -struct user_struct *find_user(uid_t uid) +struct user_struct *find_user(xid_t xid, uid_t uid) { - return uid_hash_find(uid, uidhashentry(uid)); + return uid_hash_find(xid, uid, uidhashentry(xid, uid)); } void free_uid(struct user_struct *up) @@ -78,13 +78,13 @@ void free_uid(struct user_struct *up) } } -struct user_struct * alloc_uid(uid_t uid) +struct user_struct * alloc_uid(xid_t xid, uid_t uid) { - struct list_head *hashent = uidhashentry(uid); + struct list_head *hashent = uidhashentry(xid, uid); struct user_struct *up; spin_lock(&uidhash_lock); - up = uid_hash_find(uid, hashent); + up = uid_hash_find(xid, uid, hashent); spin_unlock(&uidhash_lock); if (!up) { @@ -94,6 +94,7 @@ struct user_struct * alloc_uid(uid_t uid if (!new) return NULL; new->uid = uid; + new->vx_id = xid; atomic_set(&new->__count, 1); atomic_set(&new->processes, 0); atomic_set(&new->files, 0); @@ -103,7 +104,7 @@ struct user_struct * alloc_uid(uid_t uid * on adding the same user already.. */ spin_lock(&uidhash_lock); - up = uid_hash_find(uid, hashent); + up = uid_hash_find(xid, uid, hashent); if (up) { kmem_cache_free(uid_cachep, new); } else { @@ -148,7 +149,7 @@ static int __init uid_cache_init(void) /* Insert the root user immediately (init already runs as root) */ spin_lock(&uidhash_lock); - uid_hash_insert(&root_user, uidhashentry(0)); + uid_hash_insert(&root_user, uidhashentry(0,0)); spin_unlock(&uidhash_lock); return 0; diff -NurpP --minimal linux-2.6.0-test11/kernel/vcontext.c linux-2.6.0-test11-vs0.02/kernel/vcontext.c --- linux-2.6.0-test11/kernel/vcontext.c Thu Jan 1 01:00:00 1970 +++ linux-2.6.0-test11-vs0.02/kernel/vcontext.c Sat Dec 13 00:39:47 2003 @@ -0,0 +1,405 @@ +/* + * linux/kernel/vcontext.c + * + * Virtual Context Support + * + * Copyright (C) 2003 Herbert Pötzl + * + * V0.01 context helper + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + + +int vc_ctx_kill(uint32_t id, void *data) +{ + int retval, count=0; + struct vcmd_ctx_kill_v0 vc_data; + struct siginfo info; + struct task_struct *p; + pid_t initpid = 0; + + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + if (!vx_check(0, VX_ADMIN)) + return -EPERM; + + info.si_signo = vc_data.sig; + info.si_errno = 0; + info.si_code = SI_USER; + info.si_pid = current->pid; + info.si_uid = current->uid; + + retval = -ESRCH; + read_lock(&tasklist_lock); + switch (vc_data.pid) { + case -1: + case 0: + for_each_process(p) { + if (!initpid && vx_task_id(p) == id && p->vx_info) + initpid = p->vx_info->vx_initpid; + if (vx_task_id(p) == id && p->pid > 1 + && (!vc_data.pid || initpid != p->pid) + && thread_group_leader(p)) { + int err = send_sig_info(vc_data.sig, &info, p); + + ++count; + if (err != -EPERM) + retval = err; + } + } + break; + + default: + p = find_task_by_pid(vc_data.pid); + if (p) { + if (!thread_group_leader(p)) { + struct task_struct *tg; + + tg = find_task_by_pid(p->tgid); + if (tg) + p = tg; + } + if ((id == -1) || (vx_task_id(p) == id)) + retval = send_sig_info(vc_data.sig, &info, p); + } + break; + } + read_unlock(&tasklist_lock); + return retval; +} + +int vc_get_rlimit(uint32_t id, void *data) +{ + return -ENOSYS; +} + +int vc_set_rlimit(uint32_t id, void *data) +{ + return -ENOSYS; +} + +int vc_get_rlimit_mask(uint32_t id, void *data) +{ + return -ENOSYS; +} + + + +/* system functions */ + + +LIST_HEAD(vx_infos); + +spinlock_t vxlist_lock + __cacheline_aligned_in_smp = SPIN_LOCK_UNLOCKED; + + +/* + * struct vx_info allocation and deallocation + */ + +static struct vx_info *alloc_vx_info(int id) +{ + struct vx_info *new = NULL; + + dprintk("alloc_vx_info(%d)\n", id); + /* would this benefit from a slab cache? */ + new = kmalloc(sizeof(struct vx_info), GFP_KERNEL); + if (!new) + return 0; + + memset (new, 0, sizeof(struct vx_info)); + new->vx_id = id; + /* rest of init goes here */ + + // atomic_set(&new->limit.ticks, current->counter); // timestamp? + new->virt.nr_threads = 1; + // new->virt.bias_cswtch = kstat.context_swtch; + new->virt.bias_jiffies = jiffies; + // new->virt.bias_idle = init_tasks[0]->times.tms_utime + + // init_tasks[0]->times.tms_stime; + down_read(&uts_sem); + new->virt.utsname = system_utsname; + up_read(&uts_sem); + + dprintk("alloc_vx_info(%d) = %p\n", id, new); + return new; +} + +extern int vx_proc_destroy(struct vx_info *); + +void free_vx_info(struct vx_info *vxi) +{ + dprintk("free_vx_info(%p)\n", vxi); + vx_proc_destroy(vxi); + kfree(vxi); +} + + +/* + * struct vx_info search by id + * needs the vxlist_lock + */ + +static inline struct vx_info *__find_vx_info(int id) +{ + struct vx_info *vxi; + + list_for_each_entry(vxi, &vx_infos, vx_list) + if (vxi->vx_id == id) + return vxi; + return 0; +} + + +/* + * struct vx_info ref stuff + */ + +static struct vx_info *find_vx_info(int id) +{ + struct vx_info *vxi; + + spin_lock(&vxlist_lock); + if ((vxi = __find_vx_info(id))) + get_vx_info(vxi); + spin_unlock(&vxlist_lock); + return vxi; +} + +extern int vx_proc_create(struct vx_info *); + +static struct vx_info *find_or_create_vx_info(int id) +{ + struct vx_info *vxi, *new; + + dprintk("find_or_create_vx_info(%d)\n", id); + if (!(new = alloc_vx_info(id))) + return 0; + atomic_set(&new->vx_refcount, 1); + spin_lock(&vxlist_lock); + if ((vxi = __find_vx_info(id))) { + dprintk("find_or_create_vx_info(%d) = %p (found)\n", id, vxi); + get_vx_info(vxi); + spin_unlock(&vxlist_lock); + free_vx_info(new); + return vxi; + } + list_add(&new->vx_list, &vx_infos); + vx_proc_create(new); + dprintk("find_or_create_vx_info(%d) = %p (new)\n", id, new); + spin_unlock(&vxlist_lock); + return new; +} + + + +static int vx_migrate_user(struct task_struct *p, struct vx_info *vxi) +{ + struct user_struct *new_user, *old_user; + + if (!p || !vxi) + BUG(); + new_user = alloc_uid(vxi->vx_id, p->uid); + if (!new_user) + return -ENOMEM; + + old_user = p->user; + if (new_user != old_user) { + atomic_inc(&new_user->processes); + atomic_dec(&old_user->processes); + p->user = new_user; + } + free_uid(old_user); + return 0; +} + +/* + * migrate task to new context + * gets vxi, puts old_vxi on change + */ + +static int vx_migrate_task(struct task_struct *p, struct vx_info *vxi) +{ + struct vx_info *old_vxi; + int ret = 0; + + if (!p || !vxi) + BUG(); + + dprintk("vx_migrate_task(%p,%p[#%d.%d)\n", p, vxi, + vxi->vx_id, atomic_read(&vxi->vx_refcount)); + spin_lock(&p->alloc_lock); + if ((old_vxi = p->vx_info) == vxi) + goto out; + + if (!(ret = vx_migrate_user(p, vxi))) { + if (old_vxi) + old_vxi->virt.nr_threads--; + vxi->virt.nr_threads++; + p->vx_info = get_vx_info(vxi); + if (old_vxi) + put_vx_info(old_vxi); + } +out: + spin_unlock(&p->alloc_lock); + return ret; +} + + +static int vx_set_initpid(struct vx_info *vxi, int pid) +{ + int ret = 0; + if (vxi->vx_initpid) + ret = -EPERM; + else + vxi->vx_initpid = pid; + return ret; +} + +int vc_new_s_context(uint32_t ctx, void *data) +{ + int ret = -EPERM; + struct vcmd_new_s_context_v1 vc_data; + struct vx_info *new_vxi; + + if (copy_from_user(&vc_data, data, sizeof(vc_data))) + return -EFAULT; + switch (ctx) { + case -1: + /* allocate dynamic context */ + if (current->vx_info == NULL + || !(current->vx_info->vx_flags & VX_INFO_LOCK)) { + static int new_xid = MAX_S_CONTEXT; + static spinlock_t alloc_ctx_lock = SPIN_LOCK_UNLOCKED; + int barrier = new_xid; + int done = 0; + + do { + spin_lock(&alloc_ctx_lock); + if (++new_xid > MAX_S_CONTEXT) + new_xid = MIN_D_CONTEXT; + spin_unlock(&alloc_ctx_lock); + + new_vxi = find_or_create_vx_info(new_xid); + if (atomic_read(&new_vxi->vx_refcount) > 1) + put_vx_info(new_vxi); + else { + done = 1; + break; + } + } while (barrier != new_xid); + + if (!done) + return -EDEADLK; + + ret = vx_migrate_task(current, new_vxi); + if (ret == 0) { + current->cap_bset &= (~vc_data.remove_cap); + new_vxi->vx_flags |= vc_data.flags; + if (vc_data.flags & VX_INFO_INIT) + vx_set_initpid(new_vxi, current->tgid); + ret = new_vxi->vx_id; + } + put_vx_info(new_vxi); + } + break; + + case -2: + /* assign flags and initpid */ + if (!current->vx_info) + return -EINVAL; + ret = 0; + if (vc_data.flags & VX_INFO_INIT) + ret = vx_set_initpid(current->vx_info, current->tgid); + if (ret == 0) { + /* We keep the same vx_id, but lower the capabilities */ + current->cap_bset &= (~vc_data.remove_cap); + ret = vx_current_id(); + current->vx_info->vx_flags |= vc_data.flags; + } + break; + + case 0: + return -EINVAL; + break; + + default: + if (ctx <= 0 || ctx > MAX_S_CONTEXT) + return -EINVAL; + if (!vx_check(0, VX_ADMIN) || + !capable(CAP_SYS_ADMIN) || + (current->vx_info && + (current->vx_info->vx_flags & VX_INFO_LOCK))) + return -EPERM; + if (ctx >= MIN_D_CONTEXT) + new_vxi = find_vx_info(ctx); + else + new_vxi = find_or_create_vx_info(ctx); + if (!new_vxi) + return -EINVAL; + ret = vx_migrate_task(current, new_vxi); + if (ret == 0) { + current->cap_bset &= (~vc_data.remove_cap); + new_vxi->vx_flags |= vc_data.flags; + if (vc_data.flags & VX_INFO_INIT) + vx_set_initpid(new_vxi, current->tgid); + ret = new_vxi->vx_id; + } + put_vx_info(new_vxi); + break; + } + return ret; +} + +int vc_new_context(uint32_t ctx, void *data) +{ + int ret = -EPERM; + struct vcmd_new_s_context_v1 vc_data; + struct vx_info *vxi; + + #define MAX_S_CONTEXT 65535 /* Arbitrary limit */ + + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + if (ctx > MAX_S_CONTEXT) + return -EINVAL; + + if (vx_check(0, VX_ADMIN) + && capable(CAP_SYS_ADMIN)) { + dprintk("vxdbg: vc_new_s_context(%d)\n", ctx); + vxi = find_or_create_vx_info(ctx); + if (!vxi) + return -ENOMEM; + ret = vx_migrate_task(current, vxi); + put_vx_info(vxi); + if (ret) + return -ENOMEM; + return 0; + } + return -EPERM; +} + + + +/* set ipv4 root (syscall) */ + +int vc_set_ipv4root(uint32_t nbip, void *data) +{ + int ret = -ENOSYS; + ret = 0; + return ret; +} + diff -NurpP --minimal linux-2.6.0-test11/kernel/vswitch.c linux-2.6.0-test11-vs0.02/kernel/vswitch.c --- linux-2.6.0-test11/kernel/vswitch.c Thu Jan 1 01:00:00 1970 +++ linux-2.6.0-test11-vs0.02/kernel/vswitch.c Fri Dec 12 18:22:36 2003 @@ -0,0 +1,71 @@ +/* + * linux/kernel/vswitch.c + * + * Virtual Context Support + * + * Copyright (C) 2003 Herbert Pötzl + * + * V0.01 syscall switch + * V0.02 added signal to context + * + */ + +#include +#include +#include + +#include + + +static inline int +vc_get_version(uint32_t id) +{ + return VCI_VERSION; +} + + +extern int vc_new_s_context(uint32_t, void *); +extern int vc_set_ipv4root(uint32_t, void *); + +extern int vc_get_rlimit(uint32_t, void *); +extern int vc_set_rlimit(uint32_t, void *); +extern int vc_get_rlimit_mask(uint32_t, void *); + +extern int vc_ctx_kill(uint32_t, void *); + + +asmlinkage int +sys_vserver(uint32_t cmd, uint32_t id, void *data) +{ + int ret = -EINVAL; + + switch (cmd) { + case VCMD_get_version: + ret = vc_get_version(id); + break; + + case VCMD_new_s_context: + ret = vc_new_s_context(id, data); + break; + case VCMD_set_ipv4root: + ret = vc_set_ipv4root(id, data); + break; + + case VCMD_get_rlimit: + ret = vc_get_rlimit(id, data); + break; + case VCMD_set_rlimit: + ret = vc_set_rlimit(id, data); + break; + case VCMD_get_rlimit_mask: + ret = vc_get_rlimit_mask(id, data); + break; + + case VCMD_ctx_kill: + ret = vc_ctx_kill(id, data); + break; + + } + return ret; +} +