diff -NurpP --minimal linux-2.6.0-test9/arch/alpha/kernel/systbls.S linux-2.6.0-test9-vs0.01/arch/alpha/kernel/systbls.S --- linux-2.6.0-test9/arch/alpha/kernel/systbls.S Wed Oct 8 21:24:16 2003 +++ linux-2.6.0-test9-vs0.01/arch/alpha/kernel/systbls.S Sun Nov 16 03:32:59 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-test9/arch/i386/kernel/entry.S linux-2.6.0-test9-vs0.01/arch/i386/kernel/entry.S --- linux-2.6.0-test9/arch/i386/kernel/entry.S Wed Oct 8 21:24:03 2003 +++ linux-2.6.0-test9-vs0.01/arch/i386/kernel/entry.S Sun Nov 16 03:32:59 2003 @@ -879,6 +879,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 /* 273 sys_vserver */ nr_syscalls=(.-sys_call_table)/4 diff -NurpP --minimal linux-2.6.0-test9/arch/ppc/kernel/misc.S linux-2.6.0-test9-vs0.01/arch/ppc/kernel/misc.S --- linux-2.6.0-test9/arch/ppc/kernel/misc.S Wed Oct 8 21:24:44 2003 +++ linux-2.6.0-test9-vs0.01/arch/ppc/kernel/misc.S Sun Nov 16 03:32:59 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-test9/arch/ppc64/kernel/misc.S linux-2.6.0-test9-vs0.01/arch/ppc64/kernel/misc.S --- linux-2.6.0-test9/arch/ppc64/kernel/misc.S Sat Oct 18 14:39:36 2003 +++ linux-2.6.0-test9-vs0.01/arch/ppc64/kernel/misc.S Sun Nov 16 03:32:59 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-test9/arch/sparc/kernel/systbls.S linux-2.6.0-test9-vs0.01/arch/sparc/kernel/systbls.S --- linux-2.6.0-test9/arch/sparc/kernel/systbls.S Wed Oct 8 21:24:06 2003 +++ linux-2.6.0-test9-vs0.01/arch/sparc/kernel/systbls.S Sun Nov 16 03:32:59 2003 @@ -72,7 +72,8 @@ 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_nis_syscall +/*265*/ .long sys_timer_delete, sys_timer_create, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall +/*270*/ .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_vserver, sys_nis_syscall #ifdef CONFIG_SUNOS_EMUL /* Now the SunOS syscall table. */ diff -NurpP --minimal linux-2.6.0-test9/arch/sparc64/kernel/entry.S linux-2.6.0-test9-vs0.01/arch/sparc64/kernel/entry.S --- linux-2.6.0-test9/arch/sparc64/kernel/entry.S Wed Oct 8 21:24:00 2003 +++ linux-2.6.0-test9-vs0.01/arch/sparc64/kernel/entry.S Sun Nov 16 03:32:59 2003 @@ -26,7 +26,7 @@ #define curptr g6 -#define NR_SYSCALLS 268 /* Each OS is different... */ +#define NR_SYSCALLS 274 /* Each OS is different... */ .text .align 32 diff -NurpP --minimal linux-2.6.0-test9/arch/sparc64/kernel/systbls.S linux-2.6.0-test9-vs0.01/arch/sparc64/kernel/systbls.S --- linux-2.6.0-test9/arch/sparc64/kernel/systbls.S Wed Oct 8 21:24:04 2003 +++ linux-2.6.0-test9-vs0.01/arch/sparc64/kernel/systbls.S Sun Nov 16 03:32:59 2003 @@ -72,7 +72,8 @@ 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 + .word sys_timer_delete, sys32_timer_create, sys_ni_syscall, sys_ni_syscall, sys_ni_syscall +/*270*/ .word sys_ni_syscall, sys_ni_syscall, sys_ni_syscall, sys_vserver, sys_ni_syscall /* Now the 64-bit native Linux syscall table. */ @@ -133,7 +134,8 @@ 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_ni_syscall + .word sys_timer_delete, sys_timer_create, sys_ni_syscall, sys_ni_syscall, sys_ni_syscall +/*270*/ .word sys_ni_syscall, sys_ni_syscall, sys_ni_syscall, sys_vserver, sys_ni_syscall #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ defined(CONFIG_SOLARIS_EMUL_MODULE) @@ -233,6 +235,7 @@ sunos_sys_table: .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_nosys, sunos_nosys, sunos_nosys - .word sunos_nosys + .word sunos_nosys, sunos_nosys, sunos_nosys + .word sunos_nosys, sunos_nosys, sunos_nosys #endif diff -NurpP --minimal linux-2.6.0-test9/arch/x86_64/ia32/ia32entry.S linux-2.6.0-test9-vs0.01/arch/x86_64/ia32/ia32entry.S --- linux-2.6.0-test9/arch/x86_64/ia32/ia32entry.S Wed Oct 8 21:24:04 2003 +++ linux-2.6.0-test9-vs0.01/arch/x86_64/ia32/ia32entry.S Sun Nov 16 03:32:59 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-test9/fs/inode.c linux-2.6.0-test9-vs0.01/fs/inode.c --- linux-2.6.0-test9/fs/inode.c Sat Oct 18 14:39:36 2003 +++ linux-2.6.0-test9-vs0.01/fs/inode.c Mon Nov 17 03:26:33 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-test9/fs/proc/Makefile linux-2.6.0-test9-vs0.01/fs/proc/Makefile --- linux-2.6.0-test9/fs/proc/Makefile Wed Oct 8 21:24:01 2003 +++ linux-2.6.0-test9-vs0.01/fs/proc/Makefile Mon Nov 17 01:13:25 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-test9/fs/proc/array.c linux-2.6.0-test9-vs0.01/fs/proc/array.c --- linux-2.6.0-test9/fs/proc/array.c Sat Oct 18 14:39:36 2003 +++ linux-2.6.0-test9-vs0.01/fs/proc/array.c Mon Nov 17 00:34:18 2003 @@ -270,6 +270,7 @@ static inline char *task_cap(struct task } extern char *task_mem(struct mm_struct *, char *); + int proc_pid_status(struct task_struct *task, char * buffer) { char * orig = buffer; diff -NurpP --minimal linux-2.6.0-test9/fs/proc/base.c linux-2.6.0-test9-vs0.01/fs/proc/base.c --- linux-2.6.0-test9/fs/proc/base.c Wed Oct 8 21:24:16 2003 +++ linux-2.6.0-test9-vs0.01/fs/proc/base.c Mon Nov 17 03:44:30 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) { @@ -417,6 +423,9 @@ static int proc_permission(struct inode { if (vfs_permission(inode, mask) != 0) return -EACCES; + dprintk("vxdbg: proc_permission: [%d ~ %d]\n", inode->i_xid, vx_current_id()); + if (!vx_check_id(inode->i_xid, VX_ADMIN | VX_WATCH | VX_EQUIV)) + return -ENOENT; return proc_check_root(inode); } @@ -830,6 +839,8 @@ static int proc_pident_readdir(struct fi ret = -ENOENT; if (!pid_alive(proc_task(inode))) goto out; + if (!vx_check_id(inode->i_xid, VX_ADMIN | VX_WATCH | VX_EQUIV)) + goto out; ret = 0; pid = proc_task(inode)->pid; @@ -928,6 +939,7 @@ static struct inode *proc_pid_make_inode ei->type = ino; inode->i_uid = 0; inode->i_gid = 0; + inode->i_xid = vx_task_id(task); if (ino == PROC_TGID_INO || ino == PROC_TID_INO || task_dumpable(task)) { inode->i_uid = task->euid; inode->i_gid = task->egid; @@ -1361,6 +1373,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); @@ -1599,7 +1616,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 +1657,8 @@ static int get_tgid_list(int index, unsi for_each_process(p) { int tgid = p->pid; if (!pid_alive(p)) + continue; + if (!vx_check(p->vx_info, VX_ADMIN | VX_WATCH | VX_EQUIV)) continue; if (--index >= 0) continue; diff -NurpP --minimal linux-2.6.0-test9/fs/proc/root.c linux-2.6.0-test9-vs0.01/fs/proc/root.c --- linux-2.6.0-test9/fs/proc/root.c Wed Oct 8 21:24:26 2003 +++ linux-2.6.0-test9-vs0.01/fs/proc/root.c Mon Nov 17 01:40:27 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-test9/fs/proc/virtual.c linux-2.6.0-test9-vs0.01/fs/proc/virtual.c --- linux-2.6.0-test9/fs/proc/virtual.c Thu Jan 1 01:00:00 1970 +++ linux-2.6.0-test9-vs0.01/fs/proc/virtual.c Mon Nov 17 01:59:20 2003 @@ -0,0 +1,180 @@ +/* + * 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 + * + */ + + +#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; +} + + + + +char *vx_proc_info (struct vx_info *vxi, char *buffer) +{ + 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) +{ + int len; + char *buffer = page; + + buffer = vx_proc_info(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_status (struct vx_info *vxi, char *buffer) +{ + buffer += sprintf(buffer, + "RefC:\t%d\n" + "Flags:\t%d\n" +// "Ticks:\t%d\n" + ,atomic_read(&vxi->vx_refcount) + ,vxi->vx_flags +// ,atomic_read(&info->ticks) + ); + return buffer; +} + +int vx_status_read_func (char *page, char **start, + off_t off, int count, int *eof, void *data) +{ + int len; + char *buffer = page; + + buffer = vx_proc_status(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; +} + + +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_IDENT; +// entry->vx_id = info->vx_id[0]; + 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) +{ + int len; + char *buffer = page; + + buffer = vs_proc_info(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; +} + + +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-test9/include/asm-alpha/unistd.h linux-2.6.0-test9-vs0.01/include/asm-alpha/unistd.h --- linux-2.6.0-test9/include/asm-alpha/unistd.h Wed Oct 8 21:24:04 2003 +++ linux-2.6.0-test9-vs0.01/include/asm-alpha/unistd.h Sun Nov 16 03:32:59 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 Binary files linux-2.6.0-test9/include/asm-generic/.errno-base.h.swp and linux-2.6.0-test9-vs0.01/include/asm-generic/.errno-base.h.swp differ diff -NurpP --minimal linux-2.6.0-test9/include/asm-ppc/unistd.h linux-2.6.0-test9-vs0.01/include/asm-ppc/unistd.h --- linux-2.6.0-test9/include/asm-ppc/unistd.h Wed Oct 8 21:24:02 2003 +++ linux-2.6.0-test9-vs0.01/include/asm-ppc/unistd.h Sun Nov 16 03:32:59 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-test9/include/asm-ppc64/unistd.h linux-2.6.0-test9-vs0.01/include/asm-ppc64/unistd.h --- linux-2.6.0-test9/include/asm-ppc64/unistd.h Wed Oct 8 21:24:00 2003 +++ linux-2.6.0-test9-vs0.01/include/asm-ppc64/unistd.h Sun Nov 16 03:32:59 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-test9/include/asm-sparc/unistd.h linux-2.6.0-test9-vs0.01/include/asm-sparc/unistd.h --- linux-2.6.0-test9/include/asm-sparc/unistd.h Wed Oct 8 21:24:01 2003 +++ linux-2.6.0-test9-vs0.01/include/asm-sparc/unistd.h Sun Nov 16 03:32:59 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 /* WARNING: You MAY NOT add syscall numbers larger than 267, since * all of the syscall tables in the Sparc kernel are * sized to have 267 entries (starting at zero). Therefore diff -NurpP --minimal linux-2.6.0-test9/include/asm-sparc64/unistd.h linux-2.6.0-test9-vs0.01/include/asm-sparc64/unistd.h --- linux-2.6.0-test9/include/asm-sparc64/unistd.h Wed Oct 8 21:24:02 2003 +++ linux-2.6.0-test9-vs0.01/include/asm-sparc64/unistd.h Sun Nov 16 03:32:59 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 /* WARNING: You MAY NOT add syscall numbers larger than 267, since * all of the syscall tables in the Sparc kernel are * sized to have 267 entries (starting at zero). Therefore diff -NurpP --minimal linux-2.6.0-test9/include/asm-x86_64/ia32_unistd.h linux-2.6.0-test9-vs0.01/include/asm-x86_64/ia32_unistd.h --- linux-2.6.0-test9/include/asm-x86_64/ia32_unistd.h Wed Oct 8 21:24:16 2003 +++ linux-2.6.0-test9-vs0.01/include/asm-x86_64/ia32_unistd.h Sun Nov 16 03:32:59 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-test9/include/linux/fs.h linux-2.6.0-test9-vs0.01/include/linux/fs.h --- linux-2.6.0-test9/include/linux/fs.h Wed Oct 8 21:24:03 2003 +++ linux-2.6.0-test9-vs0.01/include/linux/fs.h Mon Nov 17 03:25:20 2003 @@ -407,6 +407,7 @@ struct inode { unsigned long i_state; + int i_xid; unsigned int i_flags; unsigned char i_sock; diff -NurpP --minimal linux-2.6.0-test9/include/linux/sched.h linux-2.6.0-test9-vs0.01/include/linux/sched.h --- linux-2.6.0-test9/include/linux/sched.h Sat Oct 18 14:39:37 2003 +++ linux-2.6.0-test9-vs0.01/include/linux/sched.h Sun Nov 16 18:01:36 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(int, uid_t); extern struct user_struct root_user; #define INIT_USER (&root_user) @@ -440,6 +441,9 @@ struct task_struct { sigset_t *notifier_mask; void *security; + struct vx_info *vx_info; + // struct iproot_info *ip_info; + // __u32 cap_bset; /* Thread group tracking */ u32 parent_exec_id; @@ -561,7 +565,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(int, uid_t); extern void free_uid(struct user_struct *); extern void switch_uid(struct user_struct *); diff -NurpP --minimal linux-2.6.0-test9/include/linux/vcontext.h linux-2.6.0-test9-vs0.01/include/linux/vcontext.h --- linux-2.6.0-test9/include/linux/vcontext.h Thu Jan 1 01:00:00 1970 +++ linux-2.6.0-test9-vs0.01/include/linux/vcontext.h Mon Nov 17 03:28:49 2003 @@ -0,0 +1,163 @@ +#ifndef _VX_CONTEXT_H +#define _VX_CONTEXT_H + +// #define DEBUG +#ifndef DEBUG +#define dprintk(x...) +#else +#define dprintk(x...) printk(x) +#endif + + +/* + We may have a different domainname and nodename for each security + context. By default, a security context share the same as its + parent, potentially the information in system_utsname +*/ +#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; + + struct new_utsname utsname; +}; + +struct _vx_limit { + atomic_t ticks; + +}; + +struct vx_info { + struct list_head vx_list; + unsigned int vx_id; + atomic_t vx_refcount; + + struct proc_dir_entry *vx_procent; + unsigned int vx_flags; + pid_t vx_initpid; + + struct _vx_virt virt; + struct _vx_limit limit; +}; + +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("vxdbg: 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("vxdbg: 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 +#define VX_EQUIV 0x0020 +#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_EQUIV) && + (__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-test9/include/linux/vswitch.h linux-2.6.0-test9-vs0.01/include/linux/vswitch.h --- linux-2.6.0-test9/include/linux/vswitch.h Thu Jan 1 01:00:00 1970 +++ linux-2.6.0-test9-vs0.01/include/linux/vswitch.h Sun Nov 16 03:20:08 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 0x00010002 + + + +/* 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 signal; +}; + +/* 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-test9/kernel/Makefile linux-2.6.0-test9-vs0.01/kernel/Makefile --- linux-2.6.0-test9/kernel/Makefile Wed Oct 8 21:24:02 2003 +++ linux-2.6.0-test9-vs0.01/kernel/Makefile Sun Nov 16 03:19:18 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-test9/kernel/fork.c linux-2.6.0-test9-vs0.01/kernel/fork.c --- linux-2.6.0-test9/kernel/fork.c Sat Oct 18 14:39:37 2003 +++ linux-2.6.0-test9-vs0.01/kernel/fork.c Sun Nov 16 22:24:41 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); } diff -NurpP --minimal linux-2.6.0-test9/kernel/sys.c linux-2.6.0-test9-vs0.01/kernel/sys.c --- linux-2.6.0-test9/kernel/sys.c Thu Nov 13 21:38:54 2003 +++ linux-2.6.0-test9-vs0.01/kernel/sys.c Sun Nov 16 21:27:10 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-test9/kernel/user.c linux-2.6.0-test9-vs0.01/kernel/user.c --- linux-2.6.0-test9/kernel/user.c Wed Oct 8 21:24:04 2003 +++ linux-2.6.0-test9-vs0.01/kernel/user.c Sun Nov 16 05:26:55 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(ctx,uid) ((((uid) >> UIDHASH_BITS) + ((uid)^(ctx))) & UIDHASH_MASK) +#define uidhashentry(ctx,uid) (uidhash_table + __uidhashfn((ctx),(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(int ctx, 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 == ctx) { 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(int ctx, uid_t uid) { - return uid_hash_find(uid, uidhashentry(uid)); + return uid_hash_find(ctx, uid, uidhashentry(ctx, 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(int ctx, uid_t uid) { - struct list_head *hashent = uidhashentry(uid); + struct list_head *hashent = uidhashentry(ctx, uid); struct user_struct *up; spin_lock(&uidhash_lock); - up = uid_hash_find(uid, hashent); + up = uid_hash_find(ctx, 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 = ctx; 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(ctx, 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-test9/kernel/vcontext.c linux-2.6.0-test9-vs0.01/kernel/vcontext.c --- linux-2.6.0-test9/kernel/vcontext.c Thu Jan 1 01:00:00 1970 +++ linux-2.6.0-test9-vs0.01/kernel/vcontext.c Mon Nov 17 01:57:37 2003 @@ -0,0 +1,237 @@ +/* + * 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) +{ + return -ENOSYS; +} + +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("vxdbg: 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 */ + + dprintk("vxdbg: 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("vxdbg: 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("vxdbg: 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("vxdbg: 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("vxdbg: 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("vxdbg: 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; +} + + +int vc_new_s_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; + return ret; +} + diff -NurpP --minimal linux-2.6.0-test9/kernel/vswitch.c linux-2.6.0-test9-vs0.01/kernel/vswitch.c --- linux-2.6.0-test9/kernel/vswitch.c Thu Jan 1 01:00:00 1970 +++ linux-2.6.0-test9-vs0.01/kernel/vswitch.c Sun Nov 16 03:20:08 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; +} +